Next.js Discord

Discord Forum

`UseRouter` Caches the Cookies should I use `redirect`?

Answered
Sun bear posted this in #help-forum
Open in Discord
Sun bearOP
Login Flow:
- Successful login saves a cookie with user information.
- I programmatically redirect to the dashboard using router.push('/dashboard'). However, this redirection is unreliable, sometimes working and sometimes not.


Logout Flow:
- Logout removes the cookie.
- The user is redirected to the login page using router.push('login'), which works as expected.

Even after logging out (and removing the cookie), if the user had previously accessed the dashboard, they can still access it despite not being authenticated.
The documentation indicates that the Next.js Router Cache https://nextjs.org/docs/app/building-your-application/caching#router-cache cannot be disabled entirely, with only "hacky refreshes" as a workaround Router Cache. This approach feels wrong . I explored using server-side redirection within a login flow through a server action (redirect). This resolves the inconsistency but doesn't this add an extra server call, potentially impacting performance, especially for a large-scale system with a separate backend?

'use server'
 
import { redirect } from 'next/navigation'
 
export async function navigate(data: string) {
  redirect(data);
}

Is there a recommended approach to address these navigation issues while maintaining optimal performance and adhering to best practices for a large-scale Next.js application? Can we leverage the Router Cache effectively while ensuring proper authentication checks?
Answered by Ray
you should use server action for the logout and redirect after that, which will invalidate the router cache when you set/delete the cookies in the server action
View full answer

33 Replies

Sun bearOP
any idea how to fix it?
@Sun bear Login Flow: - Successful login saves a cookie with user information. - I programmatically redirect to the dashboard using `router.push('/dashboard')`. However, this redirection is unreliable, sometimes working and sometimes not. Logout Flow: - Logout removes the cookie. - The user is redirected to the login page using `router.push('login')`, which works as expected. Even after logging out (and removing the cookie), if the user had previously accessed the dashboard, they can still access it despite not being authenticated. The documentation indicates that the Next.js Router Cache https://nextjs.org/docs/app/building-your-application/caching#router-cache cannot be disabled entirely, with only "hacky refreshes" as a workaround Router Cache. This approach feels wrong . I explored using server-side redirection within a login flow through a server action (redirect). This resolves the inconsistency but doesn't this add an extra server call, potentially impacting performance, especially for a large-scale system with a separate backend? js 'use server' import { redirect } from 'next/navigation' export async function navigate(data: string) { redirect(data); } Is there a recommended approach to address these navigation issues while maintaining optimal performance and adhering to best practices for a large-scale Next.js application? Can we leverage the Router Cache effectively while ensuring proper authentication checks?
you should use server action for the logout and redirect after that, which will invalidate the router cache when you set/delete the cookies in the server action
Answer
if you need to do it on client side, call router.refresh() after logout
Sun bearOP
Thanks @Ray , but does calling it using a server action considered an extra api call? It doesn't seem to be normal does it?
Sun bearOP
From the docs
?
how do you do the logout logic?
Sun bearOP
  const signOut = () => {
    Cookies.remove("sm_session");
    setSession(sessionNotFound);
    router.push("/signin");
  };
so you do it in the browser?
Sun bearOP
It is inside a context called AuthProvider
yes
Sun bearOP
I have separate backend to handle authentication
the ideal solution would be using server action like this
'use server'
 
import { redirect } from 'next/navigation'
import { cookies } from 'next/headers'

export async function signOut(data: string) {
  // handle logout
  cookies().delete("cookie")
  redirect(data);
}
Sun bearOP
so I refresh inside the signin or before router.push ?
@Sun bear so I refresh inside the signin or before `router.push` ?
  const signOut = () => {
    Cookies.remove("sm_session");
    setSession(sessionNotFound);
    router.refresh();
    router.push("/signin");
  };
it also delete the cookie
and you can't remove the cookie if the cookies is httponly on browser
Sun bearOP
Okayy that makes sense!
Thank you so much Ray! last question does the router.refresh() invalidate all routes?
@Sun bear Thank you so much Ray! last question does the `router.refresh()` invalidate all routes?
what do you mean all routes? it invalidate the router cache on the client
Sun bearOP
So the router cache is global to all routes? I thought there was a cache for each route 😅
@Sun bear So the router cache is global to all routes? I thought there was a cache for each route 😅
you are talking full route cache which is on the server
and router.fresh() is invalidating the router cache
which is on the client browser
if you need to signout a user on client side, you need router.refresh()
Sun bearOP
Okayy that makes sense. Thanks a bunch Ray!