How to Set Up Axios Interceptors in ReactJS - Kevin Uriel Fonseca
A bit of Introduction, What is Axios?
APIs are a beautiful thing. These can be found everywhere and help us to retrieve thousands of data to use however we want. However, in order to work with them, we have a need of using HTTP requests and those are made with an URL; this url usually contains the endpoints to be used and each API is different in some way or another. Axios, help us to define the main URL with something call Interceptors.
Axios as briefly mentioned before is a JavaScript library used to make HTTP requests from Node.js or XMLHttpRequests from the browser and it supports the Promise API that is native to JS ES6.
Furthermore, working with Axios as with any other JS library will give you a head ache from time to time. Axios provides several ways to initialize its APIs calls; most of the time, both techniques will ease your work flow by having you provide a baseURL value and sometimes will also request of you to provide headers. Headers are ways to identify the type of data that is being sent or retrieved from X API’s endpoint. Take a look and let’s begin!.
ReactJS vs NextJS
As everyone should know by now, ReactJS is a library created and mantained by Facebook. It’s mainly used for client-side apps that do not require heavy SEO positioning. Most of the time, the code used to make HTTP requests are run using a hook called useEffect()
. This usually runs whenever the component is mounted and then gets to display the data – depending on your Internet speed – accordingly.
NextJS, though very similar, it is not quite the same. You see, ReactJS only works in the browser, it will fetch data once the page is retrieved and that’s that, however, NextJS can also be used to make APIs! which means, that it can and will try to make any type of request way before the browser page is mounted. That’s one of the reason you sometimes notice a web page is taking a long time to load. Finally, let’s begin!.
The Serverless Framework, ReactJS:
import axios from 'axios'let apiconst logout = async () => { // HERE GOES YOUR LOGOUT FUNCTIONALITY...}// HANLDE API REQUESTSapi = axios.create({ baseURL: `http://localhost:5000/api/v1`, headers: { 'Content-Type': `application/json`, Authorization: `Bearer ${ process.window && window?.localStorage.xAuthToken }`, },})/** intercept any error responses from the api and check if the token is no longer valid. ie. Token has expired logout the user if the token has expired**/api.interceptors.response.use( async (res) => { return res }, async (err) => { let res = err?.response if (res?.status === 401 && res?.config && !res?.config?._isRetryRequest) { await logout() } })export default api;
The Server Framework, NextJS:
import { useState, createContext, useEffect } from 'react'import axios from 'axios'export const AxiosContext = createContext()export const GlobalProvider = ({ children }) => { const [auth, setAuth] = useState({ token: ``, isAuthenticated: false, user: null, }) const resetSetAuth = () => { setAuth({ token: ``, isAuthenticated: false, user: null }) } const loadUser = async () => { // HERE GOES YOUR LOAD USER FUNCTIONALITY // SHOULD RUN ONLY WHEN USER IS LOGGED IN // HERE IT IS WHERE YOU ALSO GET TO CREATE A WAY TO RETRIEVE A TOKEN AND SET IT UP IN LOCALSTORAGE } const logout = async () => { // HERE GOES YOUR LOGOUT FUNCTIONALITY... } /// process.server const token = auth && auth.token ? auth.token : '' const axiosSetup = () => { axios.defaults.baseURL = `http://localhost:5000/api/v1` axios.defaults.headers.common['Content-Type'] = `application/json` axios.defaults.headers.common['Accept'] = `application/json` axios.defaults.headers['Authorization'] = `Bearer ${token}` axios.defaults.headers.common['Authorization'] = `Bearer ${token}` axios.interceptors.response.use( async (res) => { return res }, async (err) => { let res = err?.response if ( res?.status === 401 && res?.config && !res?.config?._isRetryRequest ) { await logout() resetSetAuth() } } ) } if (process.server || typeof window !== undefined) { axiosSetup() } else { axiosSetup() } useEffect(() => { // HERE YOU NEED TO RUN THE LOAD USER FUNCTION EVERYTIME THERE'S A PAGE RELOAD }, []) return <AxiosContext.Provider>{children}</AxiosContext.Provider>}export default AxiosContext;
Bye Bye 🙂