PROBLEM: In NextJS 13, for example, your Navbar lives in the root layout.tsx folder. It checks auth, then fetches user, you want the user to be available globally to all pages regardless of server component or client component, since the Navbar exists in every route and is essentially the source of truth for the auth session, it would be unwise to fetch users on all server components when Navbar already did the work.
EDIT: better solution by tkdodo
https://tkdodo.eu/blog/zustand-and-react-context#inject-comments
OLD SOLUTION workaround:
Solution by https://www.youtube.com/watch?v=OpMAH2hzKi8
Using Zustand, a global state mangement system that doesn't require context wrappers: https://www.npmjs.com/package/zustand
Create a store
const useUserStore = create((set) => ({
signedIn: false,
setSignedIn: (isSignedIn) => set({ isSignedIn }),
}))
Create StoreInitializer.tsx:
"use client";
import { useRef } from "react";
import { useUserStore } from "@/store/userStore";
export function StoreInitializer({ user }: { user?: User }) {
const isInitialized = useRef(false);
if (!isInitialized.current) {
useUserStore.setState({
user,
});
isInitialized.current = true;
}
return null;
}
In root layout
const { user } = await useServerGetAuth(); // ur own auth function
useUserStore.setState({ user: user });
return (
<html lang="en">
<body
>
<NextTopLoader />
<StoreInitializer user={user} />
<Navbar />
{children}
<Footer />
</body>
</html>
);
Now as long as the layout successfully auth'ed the user on the server side, it'll set the user. This will also prevent flash of default values.