Виджет погоды на сайте — это почти ритуал посвящения в мир API. Вы берёте чужие данные, делаете один запрос, получаете JSON — и вдруг на вашей странице появляется живая температура. Магия. В этой статье разберём, как подключить погоду через OpenWeatherMap API: сервис бесплатный, стабильный и отлично подходит для практики. И главное — делать это будем через чистый JavaScript, без всяких серверов — и в итоге получим готовый информер погоды на сайт.
Из всех доступных погода API для разработчиков OpenWeatherMap выделяется щедрым бесплатным тарифом: до 60 запросов в минуту и до 1 000 000 запросов в месяц. Для информера на обычном сайте или блоге этого хватит с огромным запасом — разве что ваши посетители не обновляют страницу раз в секунду. Поддерживается CORS, то есть запрос можно делать прямо из браузера.
Шаг 1 — Получаем OpenWeatherMap API key
Чтобы получить OpenWeatherMap API key, идём на openweathermap.org и регистрируемся: email, пароль, подтверждение. Ничего необычного.
После входа в личный кабинет переходим на вкладку My API keys — там уже будет готовый ключ по умолчанию. Копируем и держим под рукой.
Новый ключ активируется не мгновенно — может потребоваться от нескольких минут до нескольких часов. Если сразу получаете ошибку 401 — просто подождите. Это нормально, не баг.
Шаг 2 — Разбираемся в ответе API
Прежде чем писать код, посмотрим что именно возвращает сервис. Самый простой запрос — погода по названию города:
# GET-запрос для получения текущей погоды по названию города
https://api.openweathermap.org/data/2.5/weather?q=Moscow&units=metric&lang=ru&appid=ВАШ_КЛЮЧ Параметры запроса:
- q=Moscow — название города (английское или транслит)
- units=metric — температура в градусах Цельсия. Без этого параметра вернётся Кельвин — и вы будете думать, что в Москве 286 градусов жары
- lang=ru — описание погоды на русском
- appid=... — ваш API ключ
В ответ приходит JSON. Вот его самые нужные поля:
{
"name": "Moscow", // название города
"sys": { "country": "RU" },// код страны
"main": {
"temp": 12.4, // температура в °C (при units=metric)
"feels_like": 10.8, // ощущаемая
"humidity": 72, // влажность, %
"pressure": 1013 // давление, гПа
},
"weather": [{
"description": "облачно", // текстовое описание (на русском при lang=ru)
"icon": "04d" // код иконки для отображения
}],
"wind": {
"speed": 4.2 // скорость ветра, м/с
}
} Иконки погоды — это приятный бонус: OpenWeatherMap отдаёт готовые PNG по предсказуемому URL. Берём код из поля icon и подставляем:
# URL иконки: подставьте код из поля icon в ответе API
https://openweathermap.org/img/wn/04d@2x.png Способ 1 — Погода через чистый JavaScript
OpenWeatherMap API поддерживает CORS — это значит, что запрос можно делать прямо из браузера, никакой сервер не нужен. Несколько строк JS — и готово.
При таком подходе API ключ виден в исходном коде страницы. Для личного сайта или учебного проекта это вполне приемлемо: бесплатный тариф всё равно ограничен лимитами. Если нужна дополнительная безопасность — смотрите Способ 3 ниже.
HTML-разметка виджета:
<div class="weather-widget" id="weather">
<div class="weather-widget__city">—</div>
<div class="weather-widget__temp">—</div>
<img class="weather-widget__icon" src="" alt="" />
<div class="weather-widget__desc">—</div>
<div class="weather-widget__meta">
<span class="weather-widget__wind">Ветер: —</span>
<span class="weather-widget__humidity">Влажность: —</span>
</div>
</div> JavaScript:
const API_KEY = 'ВАШ_КЛЮЧ';
const CITY = 'Moscow';
const URL = `https://api.openweathermap.org/data/2.5/weather`
+ `?q=${CITY}&units=metric&lang=ru&appid=${API_KEY}`;
fetch(URL)
.then(res => res.json())
.then(data => {
const w = document.getElementById('weather');
w.querySelector('.weather-widget__city').textContent =
`${data.name}, ${data.sys.country}`;
w.querySelector('.weather-widget__temp').textContent =
`${Math.round(data.main.temp)}°C`;
const icon = w.querySelector('.weather-widget__icon');
icon.src = `https://openweathermap.org/img/wn/${data.weather[0].icon}@2x.png`;
icon.alt = data.weather[0].description;
w.querySelector('.weather-widget__desc').textContent =
data.weather[0].description;
w.querySelector('.weather-widget__wind').textContent =
`Ветер: ${data.wind.speed} м/с`;
w.querySelector('.weather-widget__humidity').textContent =
`Влажность: ${data.main.humidity}%`;
})
.catch(() => {
document.getElementById('weather').textContent =
'Не удалось загрузить данные о погоде';
}); На что обратить внимание:
- units=metric уже возвращает Цельсии — ничего вычитать не нужно. Температура 12.4 означает 12.4 °C
- Math.round() убирает лишнее: API возвращает значения вроде 12.37, а нам нужно просто «12»
- .catch() обязателен — без него пользователь увидит пустой виджет и не поймёт что пошло не так
Способ 2 — Геолокация: город определяется автоматически
Зачем прописывать город вручную, если браузер умеет определять местоположение? navigator.geolocation — встроенный инструмент, никаких библиотек. Пользователь нажимает «Разрешить» — и видит погоду именно там, где он находится.
const API_KEY = 'ВАШ_КЛЮЧ';
function showWeather(lat, lon) {
const URL = `https://api.openweathermap.org/data/2.5/weather`
+ `?lat=${lat}&lon=${lon}&units=metric&lang=ru&appid=${API_KEY}`;
fetch(URL)
.then(res => res.json())
.then(data => {
const w = document.getElementById('weather');
w.querySelector('.weather-widget__city').textContent =
`${data.name}, ${data.sys.country}`;
w.querySelector('.weather-widget__temp').textContent =
`${Math.round(data.main.temp)}°C`;
const icon = w.querySelector('.weather-widget__icon');
icon.src = `https://openweathermap.org/img/wn/${data.weather[0].icon}@2x.png`;
icon.alt = data.weather[0].description;
w.querySelector('.weather-widget__desc').textContent =
data.weather[0].description;
w.querySelector('.weather-widget__wind').textContent =
`Ветер: ${data.wind.speed} м/с`;
w.querySelector('.weather-widget__humidity').textContent =
`Влажность: ${data.main.humidity}%`;
})
.catch(() => {
document.getElementById('weather').textContent =
'Не удалось загрузить данные';
});
}
if ('geolocation' in navigator) {
navigator.geolocation.getCurrentPosition(
pos => showWeather(pos.coords.latitude, pos.coords.longitude),
() => showWeather(55.75, 37.62) // Москва как запасной вариант
);
} Если пользователь отклонил запрос геолокации — срабатывает второй аргумент getCurrentPosition . В примере выше мы в этом случае показываем погоду Москвы по координатам — это лучше, чем пустой виджет. Можно также показать форму ввода города вручную.
Геолокация работает только на HTTPS. На обычном HTTP браузер её заблокирует. При тестировании локально используйте localhost — он является исключением и работает без сертификата.
Способ 3 — PHP как прокси: ключ остаётся на сервере
Если вам важно скрыть API ключ от посторонних — делаем тонкий серверный прокси. JavaScript запрашивает не OpenWeatherMap напрямую, а ваш PHP скрипт, который уже сам идёт к API. Ключ хранится только на сервере.
Файл weather.php :
<?php
header('Content-Type: application/json; charset=utf-8');
$apiKey = 'ВАШ_КЛЮЧ'; // хранится только здесь, снаружи не виден
$city = htmlspecialchars($_GET['city'] ?? 'Moscow', ENT_QUOTES);
$url = "https://api.openweathermap.org/data/2.5/weather"
. "?q={$city}&units=metric&lang=ru&appid={$apiKey}";
$response = file_get_contents($url);
echo $response !== false ? $response : json_encode(['error' => 'API unavailable']); JavaScript теперь обращается к вашему скрипту — структура ответа та же:
fetch('/weather.php?city=Moscow')
.then(res => res.json())
.then(data => {
document.querySelector('.weather-widget__city').textContent =
`${data.name}, ${data.sys.country}`;
document.querySelector('.weather-widget__temp').textContent =
`${Math.round(data.main.temp)}°C`;
// ... остальные поля — как в Способе 1
}); Если нужно кешировать ответ — добавьте в PHP запись в файл или базу данных и проверку времени последнего обновления. Погода редко меняется быстрее, чем раз в 10 минут, а API запросы при этом можно сократить в разы.
Пример виджета
Живой пример — виджет запрашивает геолокацию и показывает погоду в вашем городе. Если вы отклоните запрос или геолокация недоступна — покажет Москву:
Итого: как добавить погоду на сайт
- Только JavaScript — самый простой вариант. Один файл, никакого сервера. API ключ виден в коде, но для личного проекта это приемлемо.
- JavaScript + Geolocation — определяем город автоматически. Пользователь видит свою погоду без ввода чего-либо, а ваш виджет выглядит умнее.
- PHP + JavaScript — если нужна безопасность ключа или серверное кеширование. Сложнее на шаг, но ключ снаружи не виден.
Главное, что стоит запомнить: при units=metric температура приходит уже в Цельсиях — конвертировать ничего не нужно. И не забывайте .catch() — API иногда недоступен, и пользователь не должен видеть сломанный виджет.