Real-world examples of JavaScript Fetch API for modern apps
Quick-start example of JavaScript Fetch API in action
Let’s start with a minimal but realistic fetch call: requesting JSON from a public API and handling errors.
async function loadUsers() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const users = await response.json();
console.log('Users:', users);
} catch (error) {
console.error('Failed to load users:', error);
}
}
loadUsers();
This is the baseline pattern you’ll see repeated across most real examples of JavaScript Fetch API usage:
- Call
fetch(url, options). - Check
response.okandresponse.status. - Parse JSON with
response.json(). - Wrap everything in
try/catchwithasync/await.
From here, we’ll layer on more realistic scenarios.
Practical examples of JavaScript Fetch API examples for JSON APIs
Modern web apps live and die by JSON APIs. These examples of JavaScript Fetch API examples show how to handle common patterns you’ll see daily.
Example: Search with query parameters
A very common example of JavaScript Fetch API usage is a search box that calls a backend with query parameters.
async function searchBooks(query, page = 1) {
const params = new URLSearchParams({ q: query, page: String(page) });
const url = `https://openlibrary.org/search.json?${params.toString()}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Search failed: ${response.status}`);
}
const data = await response.json();
return data.docs; // array of books
}
// Usage
searchBooks('javascript').then(books => {
console.log('Found books:', books.slice(0, 3));
});
This pattern shows up in dashboards, admin panels, and any app with filters or search.
Example: POST JSON to create a resource
Another one of the best examples of JavaScript Fetch API examples is sending JSON data to create or update something on the server.
async function createTodo(title) {
const response = await fetch('https://jsonplaceholder.typicode.com/todos', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
title,
completed: false,
}),
});
if (!response.ok) {
throw new Error(`Create failed: ${response.status}`);
}
const todo = await response.json();
return todo;
}
createTodo('Write Fetch API article').then(todo => console.log(todo));
Key details:
- Always set
Content-Type: application/jsonwhen sending JSON. - Use
JSON.stringifyon the body.
Example: Updating with PATCH and handling 4xx errors
Sometimes you only want to update a single field. Here’s a PATCH example that also distinguishes user errors (4xx) from server errors (5xx).
async function markTodoDone(id) {
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ completed: true }),
});
if (!response.ok) {
if (response.status >= 400 && response.status < 500) {
const details = await response.text();
throw new Error(`Client error \({response.status}: }\(details}`);
}
throw new Error(`Server error ${response.status}`);
}
return response.json();
}
This kind of error handling is the difference between “it works on my machine” and something you can ship to production.
Authenticated examples of JavaScript Fetch API examples
Real apps rarely work with public, unauthenticated APIs. These examples include authorization headers, cookies, and token refresh patterns you’ll see in production.
Example: Bearer token with fetch
Most modern backends use Bearer tokens (often JWTs) in the Authorization header.
async function getProfile(token) {
const response = await fetch('https://api.example.com/profile', {
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json',
},
credentials: 'include', // if your API also uses cookies
});
if (!response.ok) {
throw new Error(`Profile request failed: ${response.status}`);
}
return response.json();
}
Note the use of credentials: 'include' if your API also relies on cookies. The official MDN docs have a good explanation of credentials and CORS behavior: https://developer.mozilla.org/en-US/docs/Web/API/fetch
Example: Auto-refreshing an expired token
A more advanced example of JavaScript Fetch API usage is wrapping fetch in a helper that retries when a token expires.
let accessToken = null;
async function authFetch(input, init = {}) {
if (!accessToken) {
accessToken = await getNewAccessToken();
}
const withAuth = {
...init,
headers: {
...(init.headers || {}),
'Authorization': `Bearer ${accessToken}`,
},
};
let response = await fetch(input, withAuth);
if (response.status === 401) {
// Token expired, try once more with a new token
accessToken = await getNewAccessToken();
const retryInit = {
...withAuth,
headers: {
...(withAuth.headers || {}),
'Authorization': `Bearer ${accessToken}`,
},
};
response = await fetch(input, retryInit);
}
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
return response.json();
}
This pattern is common in React, Vue, and Svelte apps that talk to OAuth2 or OpenID Connect providers.
File upload and download: real examples with Fetch
The next class of examples of JavaScript Fetch API examples covers files: sending FormData, downloading blobs, and triggering user downloads.
Example: Uploading a file with FormData
Here’s a realistic file upload example, like sending a profile picture or document.
async function uploadAvatar(file) {
const formData = new FormData();
formData.append('avatar', file);
const response = await fetch('https://api.example.com/upload-avatar', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error(`Upload failed: ${response.status}`);
}
return response.json();
}
// Usage with an <input type="file" id="avatar">
const input = document.getElementById('avatar');
input.addEventListener('change', async () => {
const file = input.files[0];
if (!file) return;
try {
const result = await uploadAvatar(file);
console.log('Upload result:', result);
} catch (error) {
console.error(error);
}
});
No Content-Type header is set manually here. The browser sets the correct multipart boundary when you pass FormData directly.
Example: Downloading a file and saving it
Another practical example of JavaScript Fetch API usage is downloading a file as a blob and triggering a save.
async function downloadReport() {
const response = await fetch('https://api.example.com/report.pdf');
if (!response.ok) {
throw new Error(`Download failed: ${response.status}`);
}
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'report.pdf';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
}
This pattern appears in internal tools, analytics dashboards, and anywhere your users export CSV or PDF data.
Streaming, AbortController, and 2024–2025 Fetch trends
In 2024–2025, the best examples of JavaScript Fetch API examples go beyond simple GET/POST. Developers are increasingly using streaming, request cancellation, and standardized APIs across environments.
Example: Canceling slow requests with AbortController
Users expect snappy interfaces. When they type in a search box, you don’t want old, slow requests overwriting new results. Here’s how to cancel outdated requests.
let currentController = null;
async function searchMovies(query) {
if (currentController) {
currentController.abort();
}
currentController = new AbortController();
const response = await fetch(`https://api.example.com/movies?q=${encodeURIComponent(query)}`, {
signal: currentController.signal,
});
if (!response.ok) {
throw new Error(`Search failed: ${response.status}`);
}
return response.json();
}
AbortController is now widely supported in browsers and in modern Node.js, which means you can use the same pattern across front-end and back-end code.
Example: Reading a streaming response
For large responses or server-sent events, streaming helps you start rendering before all data arrives. MDN has an in-depth guide on streams and ReadableStream here: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API
Here’s a simplified example of reading a text stream:
async function streamLogs() {
const response = await fetch('https://api.example.com/log-stream');
if (!response.ok || !response.body) {
throw new Error('Streaming not supported or request failed');
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
console.log('Log chunk:', chunk);
}
}
Streaming examples include live logs, AI-generated text, and any long-running process where incremental updates matter.
Using Fetch in Node.js: server-side examples
Since Node.js 18, fetch is available globally in Node without extra libraries. That means many examples of JavaScript Fetch API examples now apply both in the browser and on the server.
Example: Server-side data fetch with timeout logic
Server code often needs stricter timeouts than browsers. Here’s a Node-friendly pattern that combines fetch with AbortController.
async function fetchWithTimeout(url, { timeoutMs = 5000, ...options } = {}) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, {
...options,
signal: controller.signal,
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
return response.json();
} finally {
clearTimeout(id);
}
}
// Example usage in an Express route
// app.get('/api/weather', async (req, res) => {
// try {
// const data = await fetchWithTimeout('https://api.weather.gov/gridpoints/MPX/107,71/forecast');
// res.json(data);
// } catch (error) {
// res.status(504).json({ error: 'Upstream timeout' });
// }
// });
The National Weather Service API at https://www.weather.gov/documentation/services-web-api is a good real API to test server-side Fetch code against.
Accessibility, reliability, and data sources you can trust
When you integrate third-party APIs with Fetch, you want sources that are stable and well-documented. For health or research-oriented apps, that often means government or academic APIs.
A few examples of reliable sources you can reach with these same Fetch patterns:
- U.S. government open data via Data.gov: https://www.data.gov
- National Institutes of Health open data and APIs: https://datascience.nih.gov/data
- Academic datasets and APIs from universities such as Harvard: https://library.harvard.edu/services-tools/datasets
The examples of JavaScript Fetch API examples shown earlier can be adapted directly to these APIs: swap the URL, update headers if needed, and parse the returned JSON according to the provider’s schema.
FAQ: common questions about Fetch with real examples
What are some real examples of JavaScript Fetch API examples in production apps?
Real-world uses include:
- Autocomplete search against a product or article index
- Periodic polling of a status endpoint for long-running jobs
- Uploading images or documents via
FormData - Downloading CSV or PDF reports as blobs
- Calling internal microservices from a Node.js backend using
fetch
All of these reuse the patterns shown above: async/await, error checks, and sometimes AbortController.
Can you show an example of handling JSON and non-JSON responses in one place?
Yes. Here’s a small helper that inspects the Content-Type header:
async function fetchSmart(url, options) {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const contentType = response.headers.get('Content-Type') || '';
if (contentType.includes('application/json')) {
return response.json();
}
if (contentType.startsWith('text/')) {
return response.text();
}
return response.blob();
}
This pattern is handy when you’re calling third-party APIs that sometimes send JSON and sometimes send files.
Are these Fetch examples still relevant with libraries like Axios?
Yes. Axios is still popular, but in 2024–2025 the native Fetch API is supported across all evergreen browsers and modern Node.js. Many teams now prefer to standardize on Fetch and add a thin wrapper (like the authFetch and fetchSmart examples) instead of pulling in a separate HTTP library.
Where can I read more authoritative documentation about Fetch?
The best starting point for detailed Fetch documentation is MDN Web Docs: https://developer.mozilla.org/en-US/docs/Web/API/fetch. For server-side usage, the Node.js docs on the Fetch API are also worth reading: https://nodejs.org/api/globals.html#fetch
These real examples of JavaScript Fetch API examples are designed to drop straight into modern front-end and back-end projects. Start with the simple patterns, then layer on authentication, streaming, and cancellation as your app grows more sophisticated.
Related Topics
Explore More JavaScript Code Snippets
Discover more examples and insights in this category.
View All JavaScript Code Snippets