Centralizing HTTP Logic with Axios Interceptors
Stop repeating auth tokens and error checks in every API call. Learn how to use Axios interceptors to centralize your HTTP logic and clean up your codebase.
17 Jun 2026, 23:40 UTC

The Problem: Boilerplate Bloat in API Calls
When building a frontend application, most network requests share the same requirements: attaching a JWT (JSON Web Token) to the headers, setting a specific content type, or handling 401 Unauthorized errors by redirecting to a login page. If you handle these inside every axios.get or axios.post call, your codebase becomes cluttered with repetitive logic. This duplication makes it difficult to update your authentication strategy or error-handling rules without touching dozens of files.
What are Axios Interceptors?
Interceptors are functions that Axios executes during the request or response lifecycle. Think of them as middleware for your HTTP client. A request interceptor allows you to modify the configuration object (like headers or params) before the request is sent to the server. A response interceptor allows you to process the data or handle errors before the promise is resolved or rejected in your calling code.
These interceptors can be attached to the global Axios instance or, more ideally, to a custom instance created via axios.create(). This ensures that your interceptors only affect specific API targets rather than every single network call in your app.
Implementing Centralized Auth and Error Handling
To implement this, create a dedicated instance and attach the interceptors. In this example, we assume the application stores an access token in localStorage. This setup ensures that every request made through the api instance automatically includes the token if it exists.
import axios from 'axios';
// 1. Create a custom instance
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
});
// 2. Request Interceptor: Inject Auth Token
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('accessToken');
if (token && !config.headers.Authorization) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// 3. Response Interceptor: Global Error Handling
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response && error.response.status === 401) {
// Centralized logic for session expiration
console.warn('Session expired. Redirecting to login...');
window.location.href = '/login';
}
return Promise.reject(error);
}
);
export default api;
Managing the Interceptor Lifecycle
Interceptors are persistent for the life of the instance. If you are using a framework like React, you might need to add or remove interceptors based on the component lifecycle to avoid memory leaks or unexpected behavior. When you call .use(), Axios returns an ejector function. Calling this function removes the interceptor from the stack.
const myInterceptor = api.interceptors.request.use(config => config);
// Later, to remove the interceptor:
api.interceptors.request.eject(myInterceptor);
Practical Verification
To verify your implementation, perform the following checks:
- Header Check: Use the browser's Network tab to inspect a request. Confirm the
Authorizationheader is present without being explicitly defined in theapi.get()call. - Error Trigger: Manually change the token in
localStorageto an invalid value. Verify that the response interceptor catches the 401 status and triggers the redirect. - Ejection Test: Call the ejector function and verify that subsequent requests no longer contain the injected headers.
Trade-offs and Limitations
While powerful, interceptors introduce a layer of abstraction that can complicate debugging. Because the logic happens "behind the scenes," a developer looking at a specific API call might not realize why a header is being added or why a request is suddenly redirecting.
Additionally, be cautious with asynchronous work. If your interceptor needs to perform an async task (like refreshing a token), you must return a Promise. Heavy synchronous processing inside an interceptor will block the main thread and increase the latency of every single network request.
Summary
By moving cross-cutting concerns like authentication and error normalization into Axios interceptors, you reduce duplication and ensure consistent API behavior. Start by creating a custom Axios instance, define your request and response logic, and use ejectors to manage the lifecycle in dynamic environments.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.