Next.js Discord

Discord Forum

Auth Revalidation Help

Answered
Golden northern bumble bee posted this in #help-forum
Open in Discord
Avatar
Golden northern bumble beeOP
If we are not using fetch (so we can assign a tag like auth), how should we revalidate auth server component (say in the header) to update after things like signing in, signing out, etc...?

As of right now, I am not seeing any updates after a server action signing a user in or out and redirecting. A manual refresh does the trick but I am confused now how to approach this simple issue. Was working good in next 14 so not sure what changed.

Router.refresh does all server components so I guess I could just do that? (Cant do that in a server action though)
Answered by B33fb0n3
should I just do the page sign in redirects back to?
yes and do it like this:
revalidatePath('/the/path/where/the/client/get/redirected', 'layout')


but eventually will be wherever the user came from (redirect url
yea, let's first find the issue


---
Edit: this resolved the issue itself. The problem itself was this: https://nextjs-forum.com/post/1302296250342834226#message-1302360323894018100
After we later figured out, OP forgot to add an "await" to one of his functions that set's the cookies. Like that the cookies aren't set when the client was redirected [(see here)](https://nextjs-forum.com/post/1302296250342834226#message-1302365057845563473)
Both solving the problem
View full answer

97 Replies

Avatar
yes, router.refresh would be one option if the data is not cached somewhere. Another solution would be to use revalidatePath or revalidateTag
Avatar
Golden northern bumble beeOP
So I’m using an ORM, correct me if I’m wrong but I’d have to use fetch to use tag approach right? I do use the react cache function but that shouldn’t have any impact here as far as I’m aware.

And for revalidate path, this does not work for signing out (I don’t redirect after sign out, user stays where they are due to the nature of my site) but I’d still like UI to update.
Avatar
So I’m using an ORM, correct me if I’m wrong but I’d have to use fetch to use tag approach right?
that's wrong. Specifically for methods that don't use fetch you can use the [unstable_cache](https://nextjs.org/docs/app/api-reference/legacy-apis/unstable_cache) to also have tags or in next15 you have the [use cache](https://nextjs.org/docs/app/api-reference/directives/use-cache) methods

but I’d still like UI to update
when calling revalidateTag or revalidatePath the page will be refetched in the background and silently updated with only the new parts of the page. Like that there won't be any reload, but the UI updates to the new state
Avatar
Golden northern bumble beeOP
Ohhh I didn’t realize the ui would still update, I thought it was only after next navigation. Ok cool, and I did know about unstable cache, but tried to avoid it since it was unstable. And now the new directive is highly experimental according to Sebastian’s blog post so I’ve been trying to avoid that as well.

Screw it, maybe I’ll just use the new directive.

The interesting part of this is that I just want to try it without any caching, but something must be caching the header auth component 🤷‍♂️
I’m just confused I think lol I gotta read the docs again or something on how rendering is working
Avatar
yea... the unstable cache was and will never be stable. However many people never had issues with it and it was the only possible way to not use fetch but to still leverage the data cache. I understand you concerns about using a unstable or rather highly experimental version of a cache.

My recommendation for that is:
If you want a reliable cache for third parties: use unstable_cache
If you want to learn the next (future) syntax about caching and accept issues with it: use the use cache directive
Avatar
Golden northern bumble beeOP
Ok cool thanks, and one last question, if I have a regular old server component that is dynamically getting data (using cookies) on my page, it should not be cached at all right?
The bigger question being - it re-renders when?
Avatar
yea, a dynamic page is dynamic. It rerenders when after the server action (in your case) is done, when you using revalidateTag or revalidatePath in it
Avatar
Golden northern bumble beeOP
Ok thank you, and on navigation it should now re-render since default behavior is to not cache in v15?
Otherwise it’s gonna stay how it is until I do some explicit revalidation, refresh, or navigation to another page and back.
Avatar
yea that sounds right (without knowing your code further) and yes, the caching journey continues: https://nextjs.org/blog/our-journey-with-caching
Avatar
Golden northern bumble beeOP
Got it - I think my confusion stems from the fact that it’s a dynamic component (gets auth session with no explicit caching config), and displays sign in button or sign out button.

After I sign in (on sign in page), and the server action succeeds and redirects back to dashboard, the sign in button is still showing. At this point if I manually refresh, it’s all good (but obviously not what we want).

I expect at that point for the server component to have re-rendered. But it seems like the redirect function in a server action does not trigger anything to be re-rendered.

If this is all correct so far I guess I will have to use unstable cache with an auth tag and invalidate it as part of the server actions.

I’ll probably try using the new cache directive too since that seems to be the future approach!

Maybe it’s just me, but why does this seem to be so complicated?
Avatar
At this point if I manually refresh, it’s all good (but obviously not what we want)
that sounds more like it was cached by the browser (inside the browser cache). To invalidate that you only need to call router.refresh(). This wont trigger a page reload. It only refreshes the content that has changed and invalidates the cache.

To try a different serverside caching won't resolve the issue as it looks like it's the browser that caches it here.

Maybe it’s just me, but why does this seem to be so complicated?
well.. thinking in this kind of stuff and building everything together can be quite hard yea... Especially when you also have clientside cache for example with react query (you don't have that yet)
Avatar
Golden northern bumble beeOP
But isn’t the browser cache stale time set to 0 in v15? Meaning it’s not doing anything by default anymore?
Or are you not referring to the nextjs client router cache?
Avatar
you are right, the staleTime is no 0 by default. However there a some exceptions: (see attached). I guess one of these match your case, right?
Image
Avatar
Golden northern bumble beeOP
Hmm, I think it could only be the shared layout reason, but the sign in page uses a different layout entirely, also the header component (where the auth server component lives) is not in the DOM at all while signing in, until they are redirected back.

This would make sense for the sign out functionality (since it’s just that component changing) and rest of page stays exactly the same (my app can be used signed in or out).
Avatar
Golden northern bumble beeOP
Here is a video to help explain in case that helps
Image
Avatar
yea, did you tried it with router.refresh()? If you don't want to use router.refresh yet, open you dev tools, check the "disable cache" checkbox, reload the page and sign in to see if it's the reason of the browser cache
Avatar
Golden northern bumble beeOP
Where do I call router.refresh?
Avatar
after the result of the sign in server action
Avatar
Golden northern bumble beeOP
The sign in server action redirects
Avatar
but your clientside function should be executed to the end.

const handleButtonClick = () => {
  const signInResult = await signIn(username, password);
  console.log("this should be still executed");
}
Avatar
Golden northern bumble beeOP
Oh, for some reason I figured after the redirect the rest of the function wouldn’t run, let me try that!
Like an early return*
Avatar
yea, try and see.. iirc it should work
Avatar
Golden northern bumble beeOP
Nope, it does not run
Avatar
ah that sucks. Can you redirect on the client via router.push()?
Avatar
Golden northern bumble beeOP
Here is sign in form
Image
nothing after the executeAsync runs (if redirected/success)
Hmm let me try
Avatar
so remove the redirect function inside your server action and instead add the router.push() inside your function
Avatar
Golden northern bumble beeOP
Ok even weirder behavior now oh my...
Avatar
can you give a little more detail?
Avatar
Golden northern bumble beeOP
Without the redirect in the server action, I get cookie setting error.

Error: Cookies can only be modified in a Server Action or Route Handler.
Image
Image
Avatar
well.... yea that's weird.
Can you try this for a moment (with server action redirect)
open you dev tools, check the "disable cache" checkbox, reload the page and sign in to see if it's the reason of the browser cache [(from here)](https://nextjs-forum.com/post/1302296250342834226#message-1302349944744706128)
Avatar
Golden northern bumble beeOP
yep let me try
Same result
Image
Avatar
can you share how the button itself is rendered. Like the code for that with the condition
Avatar
Golden northern bumble beeOP
Yeah
Image
Image
Image
useAction is from "next-safe-action" package for more context
Avatar
thanks for sharing all the code. Where are you using revalidatePath or revalidateTag? That should be in the signIn function, right?
Avatar
Golden northern bumble beeOP
At the moment, there is no use of revalidate functions oor router.refresh, since I was trying to avoid the two options you mentioned at first. Is that my problem? I thought since it was dynamic it would re-render anyways when coming back but I think thats acting funky
Also, this is the function used in HeaderAuthAsync (cache function is the react one)
Image
Avatar
it was dynamic it would re-render anyways when coming
yea I thought so too...

It looks like there is some different issue with the cookies, but I don't want to focus on that right now. Can you use revalidatePath for the page that uses the sign in button?
Avatar
Golden northern bumble beeOP
It lives in my header which is on all pages, should I just do the page sign in redirects back to?

Right now, thats "/guns" but eventually will be wherever the user came from (redirect url)
Avatar
should I just do the page sign in redirects back to?
yes and do it like this:
revalidatePath('/the/path/where/the/client/get/redirected', 'layout')


but eventually will be wherever the user came from (redirect url
yea, let's first find the issue


---
Edit: this resolved the issue itself. The problem itself was this: https://nextjs-forum.com/post/1302296250342834226#message-1302360323894018100
After we later figured out, OP forgot to add an "await" to one of his functions that set's the cookies. Like that the cookies aren't set when the client was redirected [(see here)](https://nextjs-forum.com/post/1302296250342834226#message-1302365057845563473)
Both solving the problem
Answer
Avatar
Golden northern bumble beeOP
Ok trying that
Image
Avatar
looks good for me 👍
Avatar
Golden northern bumble beeOP
That worked
Avatar
that worked?
Avatar
Golden northern bumble beeOP
Yep
Image
Avatar
Nice! Now create a variables for your redirect route and add the variable to revalidatePath and the redirect itself. Like that you have one variables that makes sure everything works like expected
And depending on your case you can then change this variable depending on the client. Or make the client enter where to redirect or ... or ...
Avatar
Golden northern bumble beeOP
Ok nice that should work good! Im confused about a few things still...

1. Why I have to redirect in the server action or cookies wont work?

2. Why the header auth server component is not re-rendering upon navigation (since none of those rules you sent seem to apply)
Maybe it has to do with next-safe-action
Avatar
Well... the main issue is in the cookies: when we use revalidatePath/revalidateTag the route get rebuild in the background and sent to the client like I described. Like that the cookies are also correctly set and with that the button changes
Avatar
Golden northern bumble beeOP
According to this pic from the docs, it seems like prior to using revalidatePath, it was hitting a cache for the user info? In my case that would be the validateRequest function.

Then again, I am confused why it was cached. The react cache function I am using is just for de-duping per render cycle afaik
Image
Ah ok, so I guess the redirect is needed for the cookie to be set or something
Avatar
yea it looks like that. However: when you encounter issues with cookies or server actions in the future, keep an eye on that. That doesn't look so normal to me
Then again, I am confused why it was cached. The react cache function I am using is just for de-duping per render cycle afaik
I think it's not that really the cache. It's more when the cookies are set. Unlikely there are not that many docs about the cookies and when they are set :/

Maybe that's something that can be discussed in #discussions
Avatar
Golden northern bumble beeOP
I dont have access to that chat for some reason, I'm going to see if claude ai has any idea lol but I doubt it
Also going to check if next-safe-action could have anything to do with this, although it does not seem that way so far
Avatar
I'm going to see if claude ai has any idea lol but I doubt it
yea, I don't think AI know a solution for that when even the docs donÄt mention that clearly
Avatar
Golden northern bumble beeOP
true and its so new, prob wont bother actually
Avatar
yea, maybe that's also a possible bottleneck
Avatar
Golden northern bumble beeOP
wait a second
I might have just realized something
Avatar
Golden northern bumble beeOP
OH MY
Avatar
no stop, don't tell me..
pls
Avatar
Golden northern bumble beeOP
Hahahahaha so
Image
Avatar
💀
Avatar
Golden northern bumble beeOP
Avatar
well... at least we found anohter solution :thinkaboutit:
🤣
Avatar
Golden northern bumble beeOP
you were on the exact track of what was wrong and that helped me find that
So still
you were a HUGE help I was so damn confused
Do you get credit if you are not marked as the answer?
you have helped me like 10 times in this discord at this point lmao
Avatar
thanks for beeing that cooperative, write very fast back and trust into trying things out. Only some people do that. Thanks a lot 👏
no. Only as long as the message that you marked is from me, I will get the credit. You can see the leaderboard on the right on this website: https://nextjs-forum.com/
Avatar
Golden northern bumble beeOP
Send a message with the answer lol
Avatar
this one helped the most and also solved your initial problem
Avatar
Golden northern bumble beeOP
Yep that is good, also I removed the revalidate entirely and its still working (I think you knew that, but just to be clear)
Awesome, thank you again
Avatar
ah perfect. Happy to help and all the best for your app