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
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>;