Axios Global Interceptor Config

This is a global axios interceptor that handles requests and responses.

October 7, 2024 (3mo ago)

Axios Global Interceptor Config

Interceptor Config

  • create a new file with the name axios.ts
  • add the validation for api url from environmentConstants
import { apiBaseUrl } from "../constants/environmentConstants";
 
if (!apiBaseUrl) {
  throw new Error("No Api apiBaseUrl");
}
  • import axios from axios and add header for post request
axios.defaults.headers.post["Content-Type"] = "application/json";
  • create a function createApi that takes a path and returns an axios instance
export default const createApi = (path: string) => {
  const api = axios.create({
    baseURL: `${apiBaseUrl}${path}`,
    timeout: 10000,
    headers: {
      "Content-Type": "application/json",
    },
  });
 
  return api;
};
 
  • add the interceptor for request and responses
 
export default const createApi = (path: string) => {
  // ...
 
  api.interceptors.request.use(async (config: InternalAxiosRequestConfig) => {
  // get session from next-auth
    const session = await getSession();
    // set the access token in the header for every request after logged in
    if (session?.accessToken) {
      config.headers.set("Authorization", `Bearer ${session.accessToken}`);
    }
 
    return config;
  });
 
  api.interceptors.response.use(
    null,
    (error: AxiosError<{ statusCode: string | number; message: string }>) => {
    // handle different global error types
      if (error.message === "Network Error"){
        //handle network error
        return;
      }
      if (Number(error.response?.status) >= 500) {
        //handle 500 error
        return;
      }
      if (
        Number(error.response?.data?.statusCode) === 403 &&
        error.response?.data?.message === "Invalid User Status"
      ) {
        // handle 403 error
        return;
      }
      // return non global error for manual handling
      throw error;
    },
  );
  • example for axios.ts file will look like this
import axios, { AxiosError, InternalAxiosRequestConfig } from "axios";
import { getSession, signOut } from "next-auth/react";
import { enqueueSnackbar } from "notistack";
import { apiBaseUrl } from "../constants/environmentConstants";
 
if (!apiBaseUrl) {
  throw new Error("No Api apiBaseUrl");
}
axios.defaults.headers.post["Content-Type"] = "application/json";
export default const createApi = (path: string) => {
  const api = axios.create({
    baseURL: `${apiBaseUrl}${path}`,
    timeout: 10000,
    headers: {
      "Content-Type": "application/json",
    },
  });
  api.interceptors.request.use(async (config: InternalAxiosRequestConfig) => {
    const session = await getSession();
    if (session?.accessToken) {
      config.headers.set("Authorization", `Bearer ${session.accessToken}`);
    }
 
    return config;
  });
 
  api.interceptors.response.use(
    null,
    (error: AxiosError<{ statusCode: string | number; message: string }>) => {
      if (error.message === "Network Error")
        return enqueueSnackbar("Slow Internet", { variant: "error" });
      if (Number(error.response?.status) >= 500) {
        enqueueSnackbar("Error", { variant: "error" });
        return;
      }
      if (
        Number(error.response?.data?.statusCode) === 403 &&
        error.response?.data?.message === "Invalid User Status"
      ) {
        return signOut({ callbackUrl: "/" });
      }
      throw error;
    },
  );
 
  return api;
};

Using the axios interceptor for requests

// ... other imports
import { METHODS } from '../enums'; // enums that have all the methods
import createApi from '../utils/axios';
 
const requestApi = createApi("/url");
 
export const apiFunctionName = async ({
  params,
  requestData
}: {
  requestData: IRequestType
  params: IParamType;
}): Promise<IResponseType>> => {
  const { data } = await requestApi({
    url: '/extendedUrl',
    method: METHODS.GET, // or POST, PATCH and DELETE
    daya: requestData,
    params,
  });
 
  return data;
};

Conclusion

This is a global axios interceptor that handles requests and responses. It is a good practice to handle global errors in one place and not repeat the same code in every request.