JavaScript can retrieve weather data directly from a weather API using the built-in Fetch API available in modern browsers.
In this tutorial, we’ll use the Visual Crossing Weather API to retrieve forecast and historical weather data, process the returned JSON, and display the results in a simple web page.
If you want to explore available datasets before writing code, you can also use Visual Crossing Weather Data.
This tutorial focuses on browser-side JavaScript using:
fetch()asyncandawaitURLSearchParams- The Visual Crossing Timeline Weather API
If you are building a server-side JavaScript application with Node.js, see How to Add Weather Data to a Node.js App.
What we’ll build
We’ll start with a simple JavaScript function that retrieves weather for a location:
const weather = await getWeather("New York, NY");
We’ll then process the returned daily weather data:
weather.days.forEach(day => {
console.log(
day.datetime,
day.tempmax,
day.tempmin,
day.conditions
);
});
Finally, we’ll display the results in an HTML page.
The same Timeline Weather API can retrieve historical weather, current conditions, and forecast data, so the same JavaScript approach can support many different weather applications.
1. Get a Weather API key
Create a Visual Crossing account and obtain your Weather API key.
If you’re new to the API, see Getting Started with the Weather API.
Your API key authenticates requests made to the Weather API.
For the examples below, we’ll use:
YOUR_API_KEY
as a placeholder.
Visual Crossing plans include usage and request limits, so applications should be designed to remain within the limits of the account plan being used.
2. Understand the Timeline Weather API URL
The Timeline Weather API uses this basic request structure:
/timeline/[location]/[date1]/[date2]
Only the location is required.
A forecast request for New York looks like:
/timeline/New%20York%2CNY
A historical request for a single date looks like:
/timeline/New%20York%2CNY/2026-07-01
A historical date range looks like:
/timeline/New%20York%2CNY/2026-07-01/2026-07-07
When dates are omitted, the API returns the available forecast data. When historical dates are supplied, it returns weather data for those dates.
For the complete request reference, see the Timeline Weather API documentation.
3. Build the Weather API request
Rather than manually constructing a long query string, we can use URLSearchParams.
function buildWeatherUrl(
location,
startDate,
endDate
) {
let url =
"https://weather.visualcrossing.com/" +
"VisualCrossingWebServices/rest/services/timeline/" +
encodeURIComponent(location);
if (startDate) {
url += "/" + encodeURIComponent(startDate);
}
if (startDate && endDate) {
url += "/" + encodeURIComponent(endDate);
}
const params = new URLSearchParams({
unitGroup: "us",
include: "days",
elements:
"datetime,tempmax,tempmin,precip,precipprob,conditions",
key: "YOUR_API_KEY",
contentType: "json"
});
return `${url}?${params}`;
}
encodeURIComponent() safely encodes locations such as:
New York, NY
for use in a URL.
URLSearchParams then creates the request parameters.
In this example:
include=days
requests daily weather data, while:
elements=datetime,tempmax,tempmin,precip,precipprob,conditions
limits the response to the weather fields our application needs.
4. Retrieve weather using fetch()
Modern browsers include the Fetch API, so an additional JavaScript library is not required.
Create the following function:
async function getWeather(
location,
startDate,
endDate
) {
const url = buildWeatherUrl(
location,
startDate,
endDate
);
const response = await fetch(url);
if (!response.ok) {
const message = await response.text();
throw new Error(
`Weather API request failed ` +
`(${response.status}): ${message}`
);
}
return response.json();
}
The request is sent using:
const response = await fetch(url);
A Fetch promise does not automatically fail simply because the server returns an HTTP error such as 400, 401, or 429.
For that reason, we explicitly check:
response.ok
before processing the result.
If the request fails, we also read the response body because it can contain useful details about the cause of the error.
5. Retrieve a weather forecast
To retrieve the forecast for New York:
async function showWeather() {
try {
const weather = await getWeather(
"New York, NY"
);
console.log(
weather.resolvedAddress
);
console.log(weather.days);
} catch (error) {
console.error(error);
}
}
showWeather();
Daily weather records are returned in:
weather.days
Each daily record can contain values such as:
day.datetime
day.tempmax
day.tempmin
day.precip
day.precipprob
day.conditions
For example:
weather.days.forEach(day => {
console.log(
`${day.datetime}: ` +
`${day.conditions}, ` +
`high=${day.tempmax}, ` +
`low=${day.tempmin}`
);
});
6. Retrieve historical weather
The same JavaScript function can retrieve historical weather by supplying a date.
For example:
const weather = await getWeather(
"New York, NY",
"2026-07-01"
);
To retrieve a date range:
const weather = await getWeather(
"New York, NY",
"2026-07-01",
"2026-07-07"
);
The response uses the same days structure, so your processing code does not need to change.
If your goal is to explore or download historical datasets rather than integrate them directly into a web application, Visual Crossing Weather Data provides an interactive way to work with historical and forecast weather information.
7. Add current conditions
The Timeline Weather API can return current weather conditions as well as daily forecast data.
Change:
include: "days"
to:
include: "current,days"
Current conditions are then available in:
weather.currentConditions
For example:
console.log(
weather.currentConditions.temp
);
console.log(
weather.currentConditions.humidity
);
console.log(
weather.currentConditions.conditions
);
8. Retrieve hourly weather
To include hourly weather, change:
include: "days"
to:
include: "days,hours"
Each daily record can then contain an hours array:
const hours = weather.days[0].hours;
For example:
hours.forEach(hour => {
console.log(
hour.datetime,
hour.temp,
hour.precipprob,
hour.conditions
);
});
The Timeline API can therefore support daily forecast displays, hourly weather tables, charts, and other browser-based weather applications.
9. Display weather in a webpage
Let’s create a simple HTML container:
<h1 id="weather-location">
Weather
</h1>
<div id="weather-results">
Loading weather...
</div>
Now add a function to display the daily forecast:
function displayWeather(weather) {
const location =
document.getElementById(
"weather-location"
);
const results =
document.getElementById(
"weather-results"
);
location.textContent =
`Weather for ${weather.resolvedAddress}`;
results.innerHTML = "";
weather.days.slice(0, 5).forEach(day => {
const item =
document.createElement("div");
const date =
document.createElement("h3");
const conditions =
document.createElement("p");
const temperatures =
document.createElement("p");
date.textContent =
day.datetime;
conditions.textContent =
day.conditions ?? "";
temperatures.textContent =
`High: ${day.tempmax}°, ` +
`Low: ${day.tempmin}°`;
item.appendChild(date);
item.appendChild(conditions);
item.appendChild(temperatures);
results.appendChild(item);
});
}
Then update our request code:
async function showWeather() {
try {
const weather =
await getWeather(
"New York, NY"
);
displayWeather(weather);
} catch (error) {
console.error(error);
document.getElementById(
"weather-results"
).textContent =
"Weather data is currently unavailable.";
}
}
showWeather();
Using DOM methods such as textContent makes it easier to safely display returned text without constructing large strings of HTML.
10. Complete browser example
The following example combines the main steps into a single page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1"
>
<title>Weather API Example</title>
</head>
<body>
<h1 id="weather-location">
Weather
</h1>
<div id="weather-results">
Loading weather...
</div>
<script>
const API_KEY = "YOUR_API_KEY";
function buildWeatherUrl(
location,
startDate,
endDate
) {
let url =
"https://weather.visualcrossing.com/" +
"VisualCrossingWebServices/rest/services/timeline/" +
encodeURIComponent(location);
if (startDate) {
url += "/" +
encodeURIComponent(startDate);
}
if (startDate && endDate) {
url += "/" +
encodeURIComponent(endDate);
}
const params =
new URLSearchParams({
unitGroup: "us",
include: "days",
elements:
"datetime,tempmax,tempmin," +
"precip,precipprob,conditions",
key: API_KEY,
contentType: "json"
});
return `${url}?${params}`;
}
async function getWeather(
location,
startDate,
endDate
) {
const url =
buildWeatherUrl(
location,
startDate,
endDate
);
const response =
await fetch(url);
if (!response.ok) {
const message =
await response.text();
throw new Error(
`Weather API request failed ` +
`(${response.status}): ${message}`
);
}
return response.json();
}
function displayWeather(weather) {
document.getElementById(
"weather-location"
).textContent =
`Weather for ${weather.resolvedAddress}`;
const results =
document.getElementById(
"weather-results"
);
results.innerHTML = "";
weather.days
.slice(0, 5)
.forEach(day => {
const item =
document.createElement("div");
const date =
document.createElement("h3");
const conditions =
document.createElement("p");
const temperatures =
document.createElement("p");
date.textContent =
day.datetime;
conditions.textContent =
day.conditions ?? "";
temperatures.textContent =
`High: ${day.tempmax}°, ` +
`Low: ${day.tempmin}°`;
item.appendChild(date);
item.appendChild(conditions);
item.appendChild(temperatures);
results.appendChild(item);
});
}
async function showWeather() {
try {
const weather =
await getWeather(
"New York, NY"
);
displayWeather(weather);
} catch (error) {
console.error(error);
document.getElementById(
"weather-results"
).textContent =
"Weather data is currently unavailable.";
}
}
showWeather();
</script>
</body>
</html>
Replace:
YOUR_API_KEY
with your Visual Crossing Weather API key before testing the example.
11. API keys in browser-side JavaScript
There is an important security consideration when calling a Weather API directly from browser JavaScript.
Code sent to a browser can be inspected by the person using that browser.
That means an API key stored like this:
const API_KEY = "YOUR_API_KEY";
can be viewed by visitors to the page.
Direct browser requests are useful for demonstrations, development, and applications where exposing the key is acceptable for the intended deployment.
For public production applications, you should generally keep private credentials in server-side code and have the browser call your own application backend.
For example:
Browser
↓
Your application server
↓
Visual Crossing Weather API
If you are using server-side JavaScript, see How to Add Weather Data to a Node.js App.
12. Do I need jQuery, XMLHttpRequest, or d3?
No additional JavaScript library is required simply to retrieve Weather API data.
Older applications may use:
XMLHttpRequest- jQuery
$.get() - d3 request functions
Those approaches can still exist in established applications, but modern browser development generally uses the standard Fetch API.
If your application already uses jQuery or d3, you can still pass the resulting JSON to the same processing code shown in this tutorial.
There is usually no reason to add either library solely to make a Weather API request.
13. Handle errors carefully
A production application should be prepared for Weather API requests to fail.
Possible causes include:
- Invalid API keys
- Invalid locations
- Invalid dates
- Invalid request parameters
- Account usage limits
- Network failures
Always inspect:
response.status
and, when an error occurs:
await response.text()
The response body can contain useful details explaining why the request was unsuccessful.
14. Request only the weather data you need
The Timeline Weather API can return many different weather elements.
Use the include parameter to choose sections such as:
days
hours
current
alerts
and use elements to select specific weather fields.
For example:
const params =
new URLSearchParams({
unitGroup: "us",
include: "days",
elements:
"datetime,tempmax,tempmin,conditions",
key: API_KEY,
contentType: "json"
});
This keeps your response focused on the information your application actually uses.
For all available request options and weather fields, see the Timeline Weather API documentation.
Going further
Once your JavaScript application can retrieve Timeline Weather API data, you can build applications using:
- Historical weather
- Current conditions
- Hourly forecasts
- Daily forecasts
- Weather alerts
- Air quality
- Solar and energy weather data
- Agricultural weather variables
- Other specialized weather information
For developer-focused weather integrations, see the Visual Crossing Weather API.
For interactive access to historical and forecast datasets, see Visual Crossing Weather Data.
You can also use the Weather API Query Builder to experiment with requests and inspect the returned weather data before adding the request to your JavaScript application.
Summary
Modern JavaScript can retrieve Visual Crossing Weather API data directly using the built-in Fetch API.
The basic process is:
- Obtain a Visual Crossing Weather API key.
- Build a Timeline Weather API request for the required location and dates.
- Use
fetch()to send the request. - Check
response.okand inspect error responses when necessary. - Parse the returned JSON.
- Read daily, hourly, or current weather information.
- Display the weather data in your application.
- Keep API-key exposure in mind when using browser-side JavaScript.
For most new browser applications, fetch() with async/await provides a simpler approach than older request methods such as XMLHttpRequest, jQuery, or d3-specific HTTP helpers.

