Next.js Discord

Discord Forum

Correct way to handle logged in user in site header?

Answered
Riday πŸ’™ posted this in #help-forum
Open in Discord
What is the correct way to handle logged in user in the header/nav?
To check whether a user is logged in or not, we generally need to get the cookies / headers and do some stuff with that. When we use any of these functions, Next.js will automatically make that page as dynamic.
But, we generally add the header in the root layout. This seems to make every single page dynamic in my app. But, I don't need pages like about us, contact us, terms and conditions, etc to be dynamic.
I just want them to have a dynamic header that shows whether the user is logged in or not.
Answered by Riday πŸ’™
// layout.tsx, server component
<Header throwaway={Date.now()} />

// Header.tsx, client-component
function Header({ throwaway }: HeaderProps) {
  const { data } = useSWR(`/api/session?t=${throwaway}`);
}
View full answer

30 Replies

I have tried making the header as a client component, but revalidatePath() doesn't seem to revalidate the client side cache. I need a way to revalidate client side cache from the server or something like that
@Riday πŸ’™ Or I need to figure out a way to reset client side router state when logging in / logging out
Uhm when you implement client side rendering, shouldn’t it just work? How are you implementing client side rendering?
@joulev Uhm when you implement client side rendering, shouldn’t it just work? How are you implementing client side rendering?
// In client component, root layout > Header.tsx
const session = await fetch('/api/session');

But when I use revalidatePath(...), it's not revalidating the client side cache
So, like when I login / logout, the header still shows stale data till I refresh the page
@joulev This in a useEffect?
No... Outside
Oh wait, yes. It was in use effect
Sorry
With useState
@Riday πŸ’™ Oh wait, yes. It was in use effect
Alright.

1. The easy solution is to ditch that and use SWR/react-query to do client side rendering. Then when logging out, simply bust the client side cache that caches the auth state.

2. The dependency-less solution would be to make a client side state in a way that you can use it to force the useEffect to rerun again. This method is not pretty. Just use method 1, which is how you are recommended to do client side data fetching in react anywhere.
I guess in that case I'll have to handle redirects on the client side?
With OAuth, it's even more difficult since there is nothing on the client side
Yes your login/logout buttons need to be client components, but that shouldn’t be a problem.
@Riday πŸ’™ But, won't this refetch before the session change actually takes place?
American Crow
OMG is this the first use case of after in the help forum?? Which is even more experimental (Nextjs 15 RC) than PPR :D. I am not helping sorry, i gonna shut up now
Okay, I just thought of another (possibly bad) idea - I could pass a throwaway prop from the layout component on the server to the client-side header component that would force it to refetch or re-render. Something like Math.random() or Date.now()
@Riday πŸ’™ But, won't this refetch before the session change actually takes place?
Good point. I suppose something like this should work

<form action={async formData => {
await logout(formData)
mutate("/api/session")
router.push("/")
}}>
How does it require more code? Assuming that my current code has everything working on the server side. With this approach, I just have to write like 1 line of code and it should work... Right?
@Riday πŸ’™ How does it require more code? Assuming that my current code has everything working on the server side. With this approach, I just have to write like 1 line of code and it should work... Right?
Oh I had a different thing in mind. I thought you meant it in a completely client side way: a context+state in the root layout with a key, you change the key on login/logout and in the header you listen to changes in the key to rerun useEffect.

Yes, with server rendering it does look simpler. Try it, I think it does work yes
Okay
// layout.tsx, server component
<Header throwaway={Date.now()} />

// Header.tsx, client-component
function Header({ throwaway }: HeaderProps) {
  const { data } = useSWR(`/api/session?t=${throwaway}`);
}
Answer