Skip to content

Axios Interceptors in React: Interview Questions and Study Guide

Axios Interceptors are functions that allow you to intercept and modify HTTP requests or responses before they are handled by .then() or .catch().

  • Add JWT token automatically
  • Logging requests/responses
  • Global error handling
  • Refresh expired tokens
  • Request/Response transformation
axios.interceptors.request.use(
(config) => {
console.log("Request sent");
return config;
},
(error) => Promise.reject(error)
);

Executed before the request is sent.

axios.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${token}`;
return config;
});

Executed before the response reaches the component.

axios.interceptors.response.use(
response => response,
error => Promise.reject(error)
);

Without interceptors, every request must manually attach headers:

axios.get(url, {
headers: {
Authorization: token
}
});

With an interceptor:

axios.interceptors.request.use(config => {
config.headers.Authorization = token;
return config;
});

The token is added automatically to every request.

axios.interceptors.request.use(config => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});

This centralizes authentication logic.

axios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 500) {
alert("Server Error");
}
return Promise.reject(error);
}
);

Benefits:

  • Common error handling
  • Avoid duplicate code
axios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
window.location.href = "/login";
}
return Promise.reject(error);
}
);
import axios from "axios";
const api = axios.create({
baseURL: "https://api.example.com",
timeout: 10000
});
export default api;

Attach an interceptor:

api.interceptors.request.use(config => {
config.headers.Authorization =
`Bearer ${localStorage.getItem("token")}`;
return config;
});

Usage:

api.get("/users");
flowchart TD
    A["Request Interceptor(s)"] --> B[HTTP Request]
    B --> C[Server]
    C --> D[HTTP Response]
    D --> E["Response Interceptor(s)"]
    E --> F[Application]
Type Execution
Request Last In, First Out (LIFO)
Response First In, First Out (FIFO)

Request example:

axios.interceptors.request.use(req1);
axios.interceptors.request.use(req2);

Execution:

req2 -> req1 -> API

Response example:

axios.interceptors.response.use(res1);
axios.interceptors.response.use(res2);

Execution:

API -> res1 -> res2
const interceptorId =
axios.interceptors.request.use(config => {
return config;
});
axios.interceptors.request.eject(interceptorId);

Useful to avoid duplicate registrations and memory leaks.

axios.interceptors.response.use(
response => response,
async error => {
if (error.response.status === 401) {
const refreshResponse =
await axios.post("/refresh-token");
const newToken =
refreshResponse.data.token;
localStorage.setItem("token", newToken);
error.config.headers.Authorization =
`Bearer ${newToken}`;
return axios(error.config);
}
return Promise.reject(error);
}
);
axios.interceptors.response.use(
response => response,
async error => {
const originalRequest = error.config;
if (
error.response.status === 401 &&
!originalRequest._retry
) {
originalRequest._retry = true;
// refresh token logic
}
return Promise.reject(error);
}
);
Middleware Axios Interceptor
Runs on server Runs on client
Express/Spring Boot Axios
Handles request pipeline Handles HTTP requests/responses
Server-side Browser-side

Request logging:

axios.interceptors.request.use(config => {
console.log(config.method, config.url);
return config;
});

Response logging:

axios.interceptors.response.use(response => {
console.log(response.status, response.config.url);
return response;
});
  1. JWT Authentication
  2. Token Refresh
  3. Request Logging
  4. Response Logging
  5. Error Handling
  6. Loading Spinner Management
  7. Retry Failed Requests
  8. API Metrics Collection

Why use an Axios instance instead of global interceptors?

Section titled “Why use an Axios instance instead of global interceptors?”

Advantages:

  • Better modularity
  • Different APIs can have different configurations
  • Easier testing
  • Avoid interceptor conflicts
const authApi = axios.create();
const publicApi = axios.create();

How would you handle concurrent 401 responses?

Section titled “How would you handle concurrent 401 responses?”

If multiple requests fail simultaneously:

  • Refresh the token only once.
  • Queue the remaining failed requests.
  • Retry them after the refreshed token is available.

This avoids multiple refresh-token requests.

  • Infinite retry loops
  • Duplicate interceptor registration
  • Concurrent token refresh issues
  • Memory leaks
  • Global error handling affecting unrelated APIs

Axios Interceptors are middleware-like functions that intercept HTTP requests and responses globally, commonly used for JWT authentication, token refresh, logging, and centralized error handling.

  • Axios provides request and response interceptors for centralized HTTP handling.
  • Interceptors simplify authentication, logging, error handling, and token refresh.
  • Request interceptors execute in LIFO order, while response interceptors execute in FIFO order.
  • Use reusable Axios instances for modular and maintainable applications.
  • Prevent infinite retry loops and duplicate interceptor registration in production applications.