← Back to tutorials

Weather Dashboard

Build a weather dashboard that fetches data from an API and displays current conditions.

Intermediate⏱️ 3 hours

Overview

Create a stunning weather dashboard that fetches real-time weather data from the OpenWeatherMap API. This intermediate-level project will teach you how to work with external APIs, handle asynchronous operations, and create dynamic, data-driven interfaces. You'll build a beautiful weather app with search functionality, current conditions display, and a modern gradient design that users will love.

🎯 What You'll Learn

  • Integrate external APIs using axios and async/await
  • Manage multiple state variables for complex data
  • Handle loading states and error conditions gracefully
  • Work with environment variables for API key security
  • Parse and display JSON data from API responses
  • Create responsive, gradient-based UI designs
  • Implement search functionality with real-time updates
  • Use useEffect for component lifecycle management

🚀 Project Features

City search with instant weather updates
Current temperature and "feels like" display
Weather conditions with animated icons
Detailed metrics (humidity, wind speed, pressure)
Beautiful gradient background design
Loading states and error handling
Enter key support for quick searches
Responsive layout for all screen sizes
Smooth animations and transitions

🛠️ Technologies & Tools

React with Hooks (useState, useEffect)Axios for HTTP requestsOpenWeatherMap APICSS Grid and FlexboxEnvironment variables for securityAsync/await for asynchronous operationsModern CSS with gradients and animations

⏱️ Time Breakdown

Setup & API Configuration30 minutes
Component Structure30 minutes
API Integration45 minutes
Data Display40 minutes
Styling & Animations35 minutes

📊 Difficulty Level: Intermediate

This intermediate tutorial assumes you're comfortable with React basics and ready to tackle API integration. We'll work with asynchronous JavaScript, handle various states (loading, error, success), and create a polished user interface. The concepts learned here are directly applicable to any project requiring external data integration.

💼 Real-World Applications

The skills you learn in this tutorial are used in:

  • Weather widgets in travel applications
  • Environmental monitoring dashboards
  • Agricultural planning tools
  • Event planning applications
  • Sports and outdoor activity apps
  • Smart home control panels
  • News and media weather sections

Prerequisites:

  • React hooks
  • Async/await
  • API integration

Step 1: Setup and API Key

First, we need to set up our project and get an API key from OpenWeatherMap.

1// 1. Create a new React app
2npx create-react-app weather-dashboard
3cd weather-dashboard
4
5// 2. Install axios for API calls
6npm install axios
7
8// 3. Get a free API key from:
9// https://openweathermap.org/api
10
11// 4. Create .env file in root directory
12REACT_APP_WEATHER_API_KEY=your_api_key_here

💡 Never commit API keys to version control. Using environment variables keeps them secure.

Step 2: Create Weather Component

Let's create our main Weather component with state for storing weather data.

1import React, { useState, useEffect } from 'react';
2import axios from 'axios';
3
4function Weather() {
5 const [weather, setWeather] = useState(null);
6 const [loading, setLoading] = useState(false);
7 const [error, setError] = useState(null);
8 const [city, setCity] = useState('London');
9
10 const API_KEY = process.env.REACT_APP_WEATHER_API_KEY;
11 const API_URL = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API_KEY}&units=metric`;
12
13 return (
14 <div className="weather-dashboard">
15 <h1>Weather Dashboard</h1>
16 <div className="search-box">
17 <input
18 type="text"
19 value={city}
20 onChange={(e) => setCity(e.target.value)}
21 placeholder="Enter city name..."
22 />
23 <button>Get Weather</button>
24 </div>
25
26 {loading && <p>Loading...</p>}
27 {error && <p className="error">{error}</p>}
28 {weather && (
29 <div className="weather-info">
30 {/* Weather data will go here */}
31 </div>
32 )}
33 </div>
34 );
35}
36
37export default Weather;

💡 We set up state for weather data, loading status, errors, and the city to search for.

Step 3: Implement API Call

Now let's add the function to fetch weather data from the API.

1const fetchWeather = async () => {
2 setLoading(true);
3 setError(null);
4
5 try {
6 const response = await axios.get(API_URL);
7 setWeather(response.data);
8 } catch (err) {
9 setError('Failed to fetch weather data. Please try again.');
10 console.error('Error fetching weather:', err);
11 } finally {
12 setLoading(false);
13 }
14};
15
16// Add useEffect to fetch weather on component mount
17useEffect(() => {
18 fetchWeather();
19}, []);
20
21// Update button onClick
22<button onClick={fetchWeather}>Get Weather</button>
23
24// Handle Enter key
25const handleKeyPress = (e) => {
26 if (e.key === 'Enter') {
27 fetchWeather();
28 }
29};
30
31<input
32 type="text"
33 value={city}
34 onChange={(e) => setCity(e.target.value)}
35 onKeyPress={handleKeyPress}
36 placeholder="Enter city name..."
37/>

💡 We use async/await for cleaner asynchronous code and handle errors appropriately.

Step 4: Display Weather Data

Let's create a nice display for our weather information.

1{weather && (
2 <div className="weather-info">
3 <h2>{weather.name}, {weather.sys.country}</h2>
4 <div className="temperature">
5 <span className="temp">{Math.round(weather.main.temp)}°C</span>
6 <span className="feels-like">
7 Feels like {Math.round(weather.main.feels_like)}°C
8 </span>
9 </div>
10 <div className="description">
11 <img
12 src={`http://openweathermap.org/img/wn/${weather.weather[0].icon}@2x.png`}
13 alt={weather.weather[0].description}
14 />
15 <p>{weather.weather[0].main}</p>
16 </div>
17 <div className="details">
18 <div className="detail-item">
19 <span>Humidity</span>
20 <span>{weather.main.humidity}%</span>
21 </div>
22 <div className="detail-item">
23 <span>Wind Speed</span>
24 <span>{weather.wind.speed} m/s</span>
25 </div>
26 <div className="detail-item">
27 <span>Pressure</span>
28 <span>{weather.main.pressure} hPa</span>
29 </div>
30 </div>
31 </div>
32)}

💡 We display temperature, weather conditions, and additional details like humidity and wind speed.

Step 5: Add Styling

Let's make our weather dashboard look professional with some CSS.

1.weather-dashboard {
2 max-width: 600px;
3 margin: 50px auto;
4 padding: 30px;
5 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
6 border-radius: 20px;
7 color: white;
8 box-shadow: 0 10px 30px rgba(0,0,0,0.3);
9}
10
11.search-box {
12 display: flex;
13 margin-bottom: 30px;
14}
15
16.search-box input {
17 flex: 1;
18 padding: 15px;
19 border: none;
20 border-radius: 10px 0 0 10px;
21 font-size: 16px;
22}
23
24.search-box button {
25 padding: 15px 30px;
26 background: rgba(255,255,255,0.2);
27 color: white;
28 border: 2px solid white;
29 border-radius: 0 10px 10px 0;
30 cursor: pointer;
31 font-size: 16px;
32 transition: all 0.3s;
33}
34
35.search-box button:hover {
36 background: rgba(255,255,255,0.3);
37}
38
39.weather-info {
40 text-align: center;
41 animation: fadeIn 0.5s;
42}
43
44.temperature {
45 margin: 20px 0;
46}
47
48.temp {
49 font-size: 72px;
50 font-weight: bold;
51 display: block;
52}
53
54.feels-like {
55 font-size: 18px;
56 opacity: 0.8;
57}
58
59.description img {
60 width: 100px;
61 height: 100px;
62}
63
64.details {
65 display: grid;
66 grid-template-columns: repeat(3, 1fr);
67 gap: 20px;
68 margin-top: 30px;
69}
70
71.detail-item {
72 background: rgba(255,255,255,0.1);
73 padding: 15px;
74 border-radius: 10px;
75}
76
77@keyframes fadeIn {
78 from { opacity: 0; transform: translateY(20px); }
79 to { opacity: 1; transform: translateY(0); }
80}

💡 This creates a beautiful gradient background with smooth animations and a modern design.

🚀 Extra Challenges

Ready to take this project further? Try these challenges:

  • Add a 5-day forecast feature
  • Implement geolocation to get weather for user's current location
  • Add weather maps using a mapping library
  • Create hourly forecast display
  • Add favorite cities feature with local storage