Build a Weather Dashboard
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.
- 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:
- Go to OpenWeatherMap.org
- Create a free account
- Navigate to "My API Keys"
- Copy your API key (it may take a few minutes to activate)
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:
weather-dashboard/
├── index.html
├── style.css
├── app.js
└── config.js
Building the App
Let's start with the HTML structure:
<!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:
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:
* {
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:
// config.js
// Replace with your actual API key from OpenWeatherMap
const API_KEY = 'your-api-key-here';
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