VOOZH about

URL: https://blog.logrocket.com/intercepting-javascript-fetch-api-requests-responses/

⇱ Intercepting JavaScript Fetch API requests and responses - LogRocket Blog


2022-02-08
1210
#vanilla javascript
Indermohan Singh
91808
👁 Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

Interceptors are code blocks that you can use to preprocess or post-process HTTP calls, helping with global error handling, authentication, logging, and more. In this article, you’ll learn how to intercept JavaScript Fetch API calls.

👁 JavaScript Intercept Fetch API Responses

There are two types of events for which you may want to intercept HTTP calls, request and response events. The request interceptor should be executed before the actual HTTP request is sent, whereas the response interceptor should be executed before it reaches the application code that made the call.

Before diving into the code, we need to understand a few important factors. For one, the Fetch API doesn’t support interceptors natively. Additionally, extra packages are required to use the Fetch API in Node.js.

🚀 Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

The JavaScript Fetch API

First, let’s cover some fundamentals of the Fetch API, for example, the syntax:

const fetchResponsePromise = fetch(resource [, init])

resource defines the resource you want to fetch, which can be either a Request object or a URL. init is an optional object that will contain any custom configuration you want to apply to this particular request.

The Fetch API is promise-based. Therefore, when you call the Fetch method, you’ll get a response promise back. Here, it is referred to as fetchResponsePromise, as seen in the example above.

By default, Fetch uses the GET method for API calls, as shown below:

fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((json) => console.log(json));

Below is an example of a POST request with Fetch:

fetch('https://jsonplaceholder.typicode.com/todos', {
 method: 'POST',
 body: JSON.stringify({
 completed: false,
 id: 1,
 title: 'New Todo',
 userId: 1,
 }),
 headers: new Headers({
 'Content-Type': 'application/json; charset=UTF-8',
 }),
})
.then((response) => response.json())
.then((json) => console.log(json));

The POST call must have a body. Take a look at the Fetch documentation for more details.

Implementing interceptors

There are two ways to add interceptors to our Fetch API calls; we can either use monkey patching or the fetch-intercept library.

Monkey patching with Fetch

One way to create an interceptor for any JavaScript function or method is to monkey patch it. Monkey patching is an approach to override the original functionality with your version of the function.

Let’s take a step-by-step look at how you can create an interceptor for the Fetch API with monkey patching:

const { fetch: originalFetch } = window;

window.fetch = async (...args) => {
 let [resource, config ] = args;
 // request interceptor here
 const response = await originalFetch(resource, config);
 // response interceptor here
 return response;
};

The code above overrides the original Fetch method with a custom implementation and calls the original Fetch method inside it. You’ll use this boilerplate code to create request and response interceptors.

Request interceptor

In the following example, we’ll create a simple request interceptor that changes the resource URL of an illustration:

const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
 let [resource, config ] = args;

 // request interceptor starts
 resource = 'https://jsonplaceholder.typicode.com/todos/2';
 // request interceptor ends

 const response = await originalFetch(resource, config);

 // response interceptor here
 return response;
};


fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((json) => console.log(json));

// log
// {
// "userId": 1,
// "id": 2,
// "title": "quis ut nam facilis et officia qui",
// "completed": false
// }

This API call would fetch data from https://jsonplaceholder.typicode.com/todos/2 instead of https://jsonplaceholder.typicode.com/todos/1, as shown by the ID 2 of the todo.

Note: One of the most common use cases for request interceptors is to change the headers for authentication.

Response interceptor

The response interceptor would intercept the API response before it is delivered to the actual caller. Let’s take a look at the following code:

const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
 let [resource, config] = args;

 let response = await originalFetch(resource, config);

 // response interceptor
 const json = () =>
 response
 .clone()
 .json()
 .then((data) => ({ ...data, title: `Intercepted: ${data.title}` }));

 response.json = json;
 return response;
};

fetch('https://jsonplaceholder.typicode.com/todos/1')
 .then((response) => response.json())
 .then((json) => console.log(json));

// log
// {
// "userId": 1,
// "id": 1,
// "title": "Intercepted: delectus aut autem",
// "completed": false
// }

In the code above, we changed the JSON method to return some custom data instead of the original data. Check out the documentation to learn more about the properties that you can change.

Note: Responses are only allowed to be consumed once. Therefore, you need to clone the response each time you want to use it.

Handling errors

You can easily handle errors for requests by checking the values for response.ok and response.status. In the code snippet below, you can intercept 404 errors:

const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
 let [resource, config] = args;
 let response = await originalFetch(resource, config);
 if (!response.ok && response.status === 404) {
 // 404 error handling
 return Promise.reject(response);
 }
 return response;
};
fetch('https://jsonplaceholder.typicode.com/todos/1000000')
 .then((response) => response.json())
 .then((json) => console.log(json))
 .catch((error) => console.error(error));

Node.js

You can use the same approach in Node.js. However, Node.js doesn’t support the Fetch API natively (though native support for the Fetch API will be available in future versions of Node.js). For now, you need to install the Node Fetch package, then monkey patch the fetch method.

Using fetch-intercept library

If you’re not a fan of doing the dirty work (pun intended), the fetch-intercept library allows you to register interceptors with a cleaner API. You can use npm or Yarn to install the library as follows:

npm install fetch-intercept whatwg-fetch --save
// or
yarn install fetch-intercept whatwg-fetch

Note: The fetch-intercept library only supports browsers and won’t work in Node.js. Also, it requires whatwg-fetch as dependency to work.

With the code below, we can implement the same request and response interceptors as in our monkey patching example:

import * as fetchIntercept from 'fetch-intercept';

const unregister = fetchIntercept.register({
 request: function (url, config) {
 const modifiedUrl = `https://jsonplaceholder.typicode.com/todos/2`;
 return [modifiedUrl, config];
 },

 requestError: function (error) {
 return Promise.reject(error);
 },

 response: function (response) {
 const clonedResponse = response.clone();
 const json = () =>
 clonedResponse
 .json()
 .then((data) => ({ ...data, title: `Intercepted: ${data.title}` }));

 response.json = json;
 return response;
 },

 responseError: function (error) {
 return Promise.reject(error);
 },
});

fetch('https://jsonplaceholder.typicode.com/todos/1')
 .then((response) => response.json())
 .then((json) => console.log(json));

// unregister interceptors
unregister();

The register method allows you to register the interceptors for Fetch API calls. It takes an object with the request, requestError, response, and responseError callbacks. The register method returns another method that can be used to unregister the interceptors.

The Fetch API doesn’t support interceptors natively. However, there are other libraries for making HTTP calls that support interceptors. Take a look at Axios, which provides this functionality out of the box.

Summary

In this article, we covered what JavaScript interceptors are, learning how to create interceptors both by monkey patching the Fetch API and using the fetch-intercept library.

Originally introduced by Angular, interceptors are helpful for a wide variety of use cases, like helping with global error handling, authentication, logging, and more. You can use the methods described in this article to add interceptors to your JavaScript applications, however, keep in mind the additional required dependencies for Node.js.

I hope you enjoyed this article, be sure to leave a comment if you have any questions. Happy coding!

LogRocket: Debug JavaScript errors more easily by understanding the context

Debugging code is always a tedious task. But the more you understand your errors, the easier it is to fix them.

LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to see exactly what the user did that led to an error.

👁 LogRocket Dashboard Free Trial Banner

LogRocket records console logs, page load times, stack traces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

Try it for free.

👁 Image
👁 Image
👁 Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

Stop hardcoding LLM SDKs: Dynamic LLM routing with OpenRouter and Next.js

Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.

👁 Image
Chizaram Ken
Jun 16, 2026 ⋅ 13 min read

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension — no new framework required.

👁 Image
Ikeh Akinyemi
Jun 12, 2026 ⋅ 6 min read

How to add authentication to a React Native app with Better Auth

Learn how to build a full React Native auth system using Better Auth and Expo — with email/password login, Google OAuth, session persistence, and protected routes.

👁 Image
Chinwike Maduabuchi
Jun 9, 2026 ⋅ 13 min read

AI dev tool power rankings & comparison [June 2026]

Compare the top AI development tools and models of June 2026. View updated rankings, feature breakdowns, and find the best fit for you.

👁 Image
Chizaram Ken
Jun 8, 2026 ⋅ 11 min read
View all posts

Would you be interested in joining LogRocket's developer community?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now