🧩 API Widget Builder

Build interactive widgets with real API data

Choose Your Widget Adventure

💭

Daily Inspiration

Random quotes and motivational content

🎓 Build Your Own Widget

1

Choose API

Select an API that provides interesting data (weather, news, images, etc.)

2

Design Interface

Create HTML structure and CSS styling for your widget

3

Connect API

Use fetch() to get data and handle loading/error states

4

Add Interactivity

Enable user controls, refresh buttons, and customization options

📝 Widget Creation Examples

Basic Widget Structure

class SimpleWidget {
  constructor(containerId, apiUrl) {
    this.container = document.getElementById(containerId);
    this.apiUrl = apiUrl;
    this.init();
  }

  async init() {
    this.render();
    await this.loadData();
  }

  render() {
    this.container.innerHTML = `
      <div class="widget">
        <h3>My Widget</h3>
        <div id="data">Loading...</div>
        <button onclick="this.refresh()">Refresh</button>
      </div>
    `;
  }

  async loadData() {
    try {
      const response = await fetch(this.apiUrl);
      const data = await response.json();
      this.displayData(data);
    } catch (error) {
      this.showError(error.message);
    }
  }
}

Advanced Widget Features

class AdvancedWidget extends SimpleWidget {
  constructor(containerId, config) {
    super(containerId, config.apiUrl);
    this.config = config;
    this.cache = new Map();
    this.autoRefresh = config.autoRefresh || false;
  }

  // Caching mechanism
  async loadData(useCache = true) {
    const cacheKey = this.getCacheKey();

    if (useCache && this.cache.has(cacheKey)) {
      const cached = this.cache.get(cacheKey);
      if (Date.now() - cached.timestamp < 300000) { // 5 min cache
        this.displayData(cached.data);
        return;
      }
    }

    // Fetch new data
    const data = await this.fetchData();
    this.cache.set(cacheKey, {
      data: data,
      timestamp: Date.now()
    });

    this.displayData(data);
  }

  // Auto-refresh functionality
  enableAutoRefresh(interval = 30000) {
    this.refreshInterval = setInterval(() => {
      this.loadData(false);
    }, interval);
  }
}

Widget Styling Best Practices

/* Widget Container */
.widget {
  background: white;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.1);
  transition: transform 0.3s ease;
}

.widget:hover {
  transform: translateY(-2px);
}

/* Loading States */
.loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  color: #666;
}

.loading::before {
  content: '';
  width: 20px;
  height: 20px;
  border: 2px solid #f3f3f3;
  border-top: 2px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-right: 10px;
}

/* Responsive Grid */
.widget-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  padding: 20px;
}