Have you worked with Axios? What are interceptors in Axios
Axios is a promise-based HTTP client. Interceptors are hooks that run on every request before it's sent or every response before it resolves — used for attaching auth tokens, logging, global error handling, token refresh, and loading indicators. They centralize cross-cutting HTTP concerns.
Axios is a promise-based HTTP client for the browser and Node — over fetch it adds automatic JSON parsing, request/response transforms, instance config, timeouts, upload/download progress, easier error handling, and interceptors.
What interceptors are
Interceptors are functions Axios runs automatically on every request or response passing through an instance — middleware for HTTP. Two kinds:
// Request interceptor — runs before the request is sent
api.interceptors.request.use(
(config) => {
config.headers.Authorization = `Bearer ${getToken()}`;
return config; // must return config
},
(error) => Promise.reject(error)
);
// Response interceptor — runs before the response/error reaches your code
api.interceptors.response.use(
(response) => response, // pass through / unwrap response.data
(error) => {
if (error.response?.status === 401) redirectToLogin();
return Promise.reject(error);
}
);What they're used for
- Auth — attach the access token to every request; on a 401, attempt a token refresh and retry the original request (queue concurrent requests during refresh).
- Global error handling — map status codes to behaviors (401 → logout, 403 → forbidden page, 5xx → toast), so each call site doesn't repeat it.
- Logging / monitoring — log every request/response, report failures.
- Loading state — increment/decrement a global in-flight counter for a top-level spinner.
- Headers / config — base URL, correlation ids, locale, content-type defaults.
- Transforming — camelCase ↔ snake_case, unwrap
response.data. - Retries — backoff retry on transient failures.
Why they matter
They centralize cross-cutting concerns. Without interceptors, every API call re-implements auth headers, error handling, and logging. With them, it's defined once on the instance.
const api = axios.create({ baseURL: "/api", timeout: 10000 });
// register interceptors once; every api.get/post inherits themGotchas / good practice
- A request interceptor must return
config(or a promise of it); a response interceptor must return the response or reject. - The token-refresh-and-retry flow is the classic tricky case — guard against infinite loops, and queue requests that arrive mid-refresh so they don't each trigger a refresh.
- You can
ejectinterceptors; order matters when you register several. - Modern note: many teams now wrap
fetch(or use React Query'sfetcher) and replicate this with a small client — but the interceptor concept (centralized request/response middleware) is the thing to understand.
How to answer
"Yes — Axios is a promise-based HTTP client; the feature I lean on most is interceptors. I use a request interceptor to attach the auth token and a response interceptor for global error handling and the 401 → refresh-and-retry flow, so cross-cutting HTTP concerns live in one place instead of every call site."
Follow-up questions
- •Walk through implementing token refresh in a response interceptor.
- •How do you avoid an infinite loop in a refresh interceptor?
- •What does Axios give you over fetch?
- •How would you handle concurrent requests that all get a 401 during a refresh?
Common mistakes
- •Forgetting to return config from a request interceptor.
- •A refresh interceptor that loops infinitely on repeated 401s.
- •Not queuing concurrent requests during a token refresh — each triggers its own.
- •Putting auth/error logic at every call site instead of in an interceptor.
Performance considerations
- •Interceptors run on every request/response — keep them light. The refresh-and-retry queue prevents a thundering herd of refresh calls.
Edge cases
- •Multiple requests failing with 401 simultaneously during refresh.
- •The refresh request itself failing.
- •Interceptor order when several are registered.
- •Request cancellation interacting with interceptors.
Real-world examples
- •An axios instance with a request interceptor for auth and a response interceptor doing 401 -> refresh -> retry with a request queue.
- •A global loading spinner driven by an in-flight counter incremented/decremented in interceptors.