← Back to Tutorials
JavaScript

Build a Weather Dashboard

Difficulty: Beginner Est. Time: ~2 hours

Introduction

In this tutorial, you'll build a beautiful weather dashboard that fetches real-time weather data from an API. The app will display current conditions and a 5-day forecast with smooth animations.

What You'll Learn
  • Making HTTP requests with the Fetch API
  • Working with external APIs (OpenWeatherMap)
  • Asynchronous JavaScript (async/await)
  • CSS animations and transitions

Prerequisites

Before starting this tutorial, you should have:

  • Basic knowledge of HTML and CSS
  • Understanding of JavaScript fundamentals
  • A code editor (VS Code recommended)
  • A modern web browser

Getting an API Key

We'll use the OpenWeatherMap API for weather data. Follow these steps:

  1. Go to OpenWeatherMap.org
  2. Create a free account
  3. Navigate to "My API Keys"
  4. Copy your API key (it may take a few minutes to activate)
Keep Your API Key Safe

Never commit your API key to version control. In production, you'd want to proxy requests through a backend server.

Project Setup

Create your project files:

File Structure
weather-dashboard/
├── index.html
├── style.css
├── app.js
└── config.js

Building the App

Let's start with the HTML structure:

HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Weather Dashboard</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="weather-app">
        <div class="search-box">
            <input type="text" id="city-input" placeholder="Enter city name...">
            <button id="search-btn">🔍</button>
        </div>

        <div id="current-weather" class="current-weather">
            <h2></h2>
            <div class="temperature"></div>
            <div class="description"></div>
            <div class="humidity"></div>
        </div>

        <div class="forecast" id="forecast"></div>
    </div>

    <script src="config.js"></script>
    <script src="app.js"></script>
</body>
</html>

Now let's create the JavaScript to fetch weather data:

JavaScript
const API_KEY = YOUR_API_KEY_HERE;
const BASE_URL = 'https://api.openweathermap.org/data/2.5';

const cityInput = document.getElementById('city-input');
const searchBtn = document.getElementById('search-btn');
const currentWeather = document.getElementById('current-weather');
const forecast = document.getElementById('forecast');

// Fetch current weather data
async function getCurrentWeather(city) {
    try {
        const response = await fetch(
            `${BASE_URL}/weather?q=${city}&appid=${API_KEY}&units=metric`
        );
        
        if (!response.ok) throw new Error('City not found');
        
        const data = await response.json();
        displayCurrentWeather(data);
    } catch (error) {
        alert(error.message);
    }
}

// Fetch 5-day forecast
async function getForecast(city) {
    try {
        const response = await fetch(
            `${BASE_URL}/forecast?q=${city}&appid=${API_KEY}&units=metric`
        );
        
        const data = await response.json();
        displayForecast(data);
    } catch (error) {
        console.error(error);
    }
}

// Display current weather
function displayCurrentWeather(data) {
    const { name, main, weather } = data;
    
    currentWeather.innerHTML = <?>`
        <h2>${name}</h2>
        <div class="temperature">${Math.round(main.temp)}°C</div>
        <div class="description">${weather[0].description}</div>
        <div class="humidity">Humidity: ${main.humidity}%</div>
    `;
    
    currentWeather.classList.add('fade-in');
}

// Display forecast
function displayForecast(data) {
    const daily = data.list.filter((_, index) => index % 8 === 0);
    
    forecast.innerHTML = daily.map(day => <?>`
        <div class="forecast-day">
            <div class="day-name">${new Date(day.dt * 1000).toLocaleDateString('en-US', { weekday: 'short' })}</div>
            <div class="day-temp">${Math.round(day.main.temp)}°C</div>
        </div>
    `).join('');
}

// Event listeners
searchBtn.addEventListener('click', () => {
    const city = cityInput.value.trim();
    if (city) {
        getCurrentWeather(city);
        getForecast(city);
    }
});

cityInput.addEventListener('keypress', (e) => {
    if (e.key === 'Enter') {
        searchBtn.click();
    }
});

Adding Styles

Let's make our weather dashboard look stunning:

CSS
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    min-height: 100vh;
    background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 2rem;
}

.weather-app {
    background: rgba(255, 255, 255, 0.95);
    border-radius: 20px;
    padding: 2rem;
    width: 100%;
    max-width: 500px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.search-box {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 2rem;
}

.search-box input {
    flex: 1;
    padding: 1rem;
    border: 2px solid #e0e0e0;
    border-radius: 10px;
    font-size: 1rem;
    transition: border-color 0.3s;
}

.search-box input:focus {
    outline: none;
    border-color: #2a5298;
}

.search-box button {
    padding: 1rem 1.5rem;
    background: #2a5298;
    color: white;
    border: none;
    border-radius: 10px;
    cursor: pointer;
    font-size: 1.2rem;
}

.temperature {
    font-size: 4rem;
    font-weight: 700;
    color: #1e3c72;
}

.forecast {
    display: flex;
    justify-content: space-between;
    margin-top: 2rem;
    padding-top: 1rem;
    border-top: 1px solid #e0e0e0;
}

.forecast-day {
    text-align: center;
}

.fade-in {
    animation: fadeIn 0.5s ease-in;
}

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

Final Touches

Create a config.js file to store your API key:

JavaScript
// config.js
// Replace with your actual API key from OpenWeatherMap
const API_KEY = 'your-api-key-here';
Congratulations!

Your weather dashboard is now complete. Open index.html in your browser, enter a city name, and see the weather data come to life!

Conclusion

Congratulations! You've built a complete weather dashboard application. Let's review what you learned and built.

What You Built

  • Weather Dashboard UI - A clean, modern interface for displaying weather
  • API Integration - Connected to OpenWeatherMap API for real data
  • Async JavaScript - Used fetch() and async/await for API calls
  • 5-Day Forecast - Displayed upcoming weather predictions
  • Error Handling - Gracefully handle API errors and invalid cities

Key Concepts Learned

  • Working with external APIs (RESTful APIs)
  • Asynchronous JavaScript patterns
  • JSON data parsing and manipulation
  • CSS animations and transitions
  • User input validation

Next Steps

Try adding these features to enhance your weather app:

  • Add weather icons for different conditions
  • Implement geolocation to get user's local weather
  • Add a 7-day forecast instead of 5-day
  • Create a dark/light theme toggle
  • Add temperature unit conversion (Celsius/Fahrenheit)
  • Show humidity, wind speed, and pressure
  • Add weather alerts and notifications

Continue Learning

Ready for more? Try these tutorials:

  • Build a Task Manager - Learn local storage and DOM manipulation
  • Build a URL Shortener - API design and database
  • Build a Chat App - Real-time communication