Search code examples
reactjsnext.jsauth0

Why is @auth0/nextjs-auth0 invoking /me api everytime I change route?


I just started using auth0 sdk for nextjs projects. Everything seems to be ok, but I have one little problem. Everytime I change route (while I am logged in) there is invoked the /me api. This means that the user that I got through useUser ctx becomes undefined and there is a little flash of the pages rendered only if logged in.

This is the general structure of my project

_app.tsx

import "../styles/globals.css";
import type { AppProps } from "next/app";
import { appWithTranslation } from "next-i18next";
import { UserProvider } from "@auth0/nextjs-auth0/client";
import AppMenu from "../components/AppMenu";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <UserProvider>
      <AppMenu>
          <Component {...pageProps} />
      </AppMenu>
    </UserProvider>
  );
}

export default appWithTranslation(MyApp);

AppMenu is a component that I render only if I have the user. It's something like:

import { NextPage } from "next";
import { useUser } from "@auth0/nextjs-auth0/client";

interface Props {
  children: JSX.Element;
}

const AppMenu: NextPage<Props> = ({ children }) => {
  const { user } = useUser();
  

  return (
    <div>
      {user && (<nav>{/* more stuff...*/}</nav>) }
      {children}
    </div>
  );
};

export default AppMenu;

In this component I have the app's menu.

As I said before, when I switch from a route to another I can see in the network tab that there is called the /me endpoint and "user" is undefined. This implies that the app's menu (and all the protected components) is not rendered and there is a nasty flash of the page waiting for the response.

Is there a way to fix this? I was looking for a isLoggedIn prop but I haven't found anything.

What do you suggest?

p.s. Possibly, I would avoid a "loading" component


Solution

  • useUser() is a hooks call. Therefore, you need to use useEffect() with a Promise and wait until load the user. However, by the end of the day loading component is a must.

    In the meantime, A feature called isLoading comes up with the useUser() state. You can improve your code like the below.

    const { user, error, isLoading } = useUser();
    
    if (isLoading) return <div>Loading...</div>;
    if (error) return <div>{error.message}</div>;
    
    

    Source