When building Weather & Clock Dashboard — a Firefox new tab extension — one of my core requirements was: no user accounts, no API keys, no data sent to my servers.
This post covers how I achieved that using Open-Meteo, a completely free weather API.
Why Open-Meteo?
Most weather APIs require:
- Registration + API key management
- Rate limits tied to an account
- Potential privacy concerns about who's tracking what
Open-Meteo requires none of that. It's:
- 100% free (10,000 requests/day without an API key)
- No registration needed
- Open-source
- GDPR-compliant by design
The Approach
The extension uses the browser's built-in Geolocation API to get coordinates, then makes a simple HTTP request to Open-Meteo.
Step 1: Get user location
navigator.geolocation.getCurrentPosition(
(position) => {
const { latitude, longitude } = position.coords;
fetchWeather(latitude, longitude);
},
(error) => {
console.warn('Geolocation denied:', error);
// Show manual location input
}
);
The user sees a browser permission prompt. If they deny it, I fall back to a manual city name input.
Step 2: Geocode city name (optional fallback)
When the user types a city name, I use the Open-Meteo Geocoding API:
async function geocodeCity(cityName) {
const url = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(cityName)}&count=1&language=en&format=json`;
const response = await fetch(url);
const data = await response.json();
if (data.results && data.results.length > 0) {
const { latitude, longitude } = data.results[0];
return { latitude, longitude };
}
throw new Error('City not found');
}
Step 3: Fetch weather data
async function fetchWeather(lat, lon) {
const url = new URL('https://api.open-meteo.com/v1/forecast');
url.searchParams.set('latitude', lat);
url.searchParams.set('longitude', lon);
url.searchParams.set('current', 'temperature_2m,weathercode,windspeed_10m');
url.searchParams.set('daily', 'weathercode,temperature_2m_max,temperature_2m_min');
url.searchParams.set('timezone', 'auto');
url.searchParams.set('forecast_days', '4');
const response = await fetch(url.toString());
const data = await response.json();
return {
current: data.current,
daily: data.daily,
timezone: data.timezone
};
}
Step 4: Map weather codes to icons
Open-Meteo returns WMO weather codes. Here's a minimal mapping:
const WEATHER_ICONS = {
0: '☀️', // Clear sky
1: '🌤️', 2: '⛅', 3: '☁️', // Partly/mostly cloudy
45: '🌫️', 48: '🌫️', // Fog
51: '🌦️', 53: '🌦️', 55: '🌧️', // Drizzle
61: '🌧️', 63: '🌧️', 65: '🌧️', // Rain
71: '🌨️', 73: '🌨️', 75: '❄️', // Snow
80: '🌦️', 81: '🌧️', 82: '⛈️', // Rain showers
95: '⛈️', 96: '⛈️', 99: '⛈️', // Thunderstorm
};
function getWeatherIcon(code) {
return WEATHER_ICONS[code] || '🌡️';
}
Result
Zero external dependencies beyond the browser itself. The entire extension is ~300 lines of vanilla HTML/CSS/JS, works offline (shows cached data), and never touches a backend server.
Extension link: Weather & Clock Dashboard on Firefox Add-ons
GitHub: github.com/weatherclockdash/weather-clock-dashboard (MIT licensed)
Have you used Open-Meteo in your projects? I'd love to hear other use cases in the comments.
Top comments (0)