0

I'm working on a Next.js 15 project using the App Router and trying to implement an Axios interceptor as a custom hook to handle authentication and token refresh. My current implementation is losing the interceptor on page refresh and I want to properly manage client-side hooks within the interceptor.

This is my current implementation

export const AxiosInterceptor = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const { accessToken, refreshToken } = useAppSelector((state) => state.auth);
  const dispatch = useAppDispatch();

  const interceptorId = useRef<number | null>(null);

  const reqInterceptor = async (request: any) => {
    request.headers["authorization"] = `Bearer ${accessToken}`;

    if (hasTokenExpired(accessToken!)) {
      const newAccessToken = await getNewAccessToken(refreshToken!);
      if (!newAccessToken) {
        throw new Error("Current session expired");
      }

      dispatch(setToken({ accessToken: newAccessToken }));
      request.headers["authorization"] = `Bearer ${newAccessToken}`;
    }

    return request;
  };

  const errInterceptor = (error: any) => Promise.reject(error);

  useEffect(() => {
    // Attach the interceptor and store its ID in useRef
    interceptorId.current = AuthInstance.interceptors.request.use(
      reqInterceptor,
      errInterceptor
    );

    // Cleanup function to eject the interceptor
    return () => {
      if (interceptorId.current !== null) {
        AuthInstance.interceptors.request.eject(interceptorId.current);
      }
    };
  }, [reqInterceptor, errInterceptor]);

  return children;
};

Root layout

const RootLayout = ({ children }: { children: ReactNode }) => {
  return (
    <html lang="en">
      <body className={`${dmSans.className}  antialiased `}>
        <BgPattern className="top-20 left-40 " />
        <BgPattern className="bottom-20 right-40 " />
        <main>
          <StoreProvider>
            <AxiosInterceptor>{children}</AxiosInterceptor>
          </StoreProvider>
          <Toaster />
        </main>
      </body>
    </html>
  );
};

I want to:

  1. Use this instance across my application
  2. Handle token refresh and authentication properly
  3. Ensure the interceptor persists across page refreshes

Environment:

Next.js 15 App Router Redux for state management Axios for API calls TypeScript

1
  • Update: I figured out the fix i just need to add an isReady state within the component and return the children once the interceptor is ready.
    – Parvesh
    Commented Dec 12, 2024 at 16:47

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.