Next.js Discord

Discord Forum

Cookies in server action : Dynamic server usage ? Any correct way to handle that please ?

Answered
tensefrogomar posted this in #help-forum
Open in Discord
Hey guys,
I hope you're all doing great ! I have a question on how or what is the correct way to handle the error

[Error]: Dynamic server usage: Route /dashbo... couldn't be rendered statically because it used cookies. See more info here: https://nextjs.org/docs/messages/dynamic-server-error

The solution doesn't look like it will solve my problem :

I have a server action where i made my call to my api using fetch
Looks like this

'use server'
import 'server-only';
export async function getMyShopsAction(): Promise<Sh..Response> {
const url = ${API_URL}/sh...
try {
const cookieStore = await cookies();
const authToken = cookieStore.get('auth-store');


So based on the answer i found on the internet i can :

1 - use dynamic = 'force-dynamic'
2 - use noStore()
3 - use dynamic = 'force-dynamic' + revalidate

4 - i got the idea of creating some client component like a middlewear where i would use the cookies ...
Then use it in my getMyShopsAction() ...

So what do you guys think ? or if anyone has some official docs to solve my problem guys please ! It will be a big help

Thank you for reading me and have nice day
Answered by Spectacled Caiman
Hey so this error happens because Next js is trying to statically pre render your dashboard page at build time but your server action calls cookies which makes it dynamic!!!! The thing is you actually want this page to be dynamic since you need user specific auth data on every request so the solution is totally fine to use!!!!

Heres what you should do, in your page file for dashboard add export const dynamic = force-dynamic at the top level, this tells Next js to skip static rendering for that ROUTEEE and render it on demand every time!!!! You dont need noStore or a client component middleware workaround, just force dynamic is the cleanest approach for auth protected pages that read cookies!!!! The error will disappear and your page will render correctly with the auth token from cookies on every request!!!! If you want more control you can also use export const revalidate = 0 but force dynamic is simpler for pages that always need fresh user data!!!! This is the official Next js way to handle dynamic data like cookies and its totally expected for dashboard or protected routessss!!!!
View full answer

16 Replies

@tensefrogomar Hey guys, I hope you're all doing great ! I have a question on how or what is the correct way to handle the error [Error]: Dynamic server usage: Route /dashbo... couldn't be rendered statically because it used `cookies`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error The solution doesn't look like it will solve my problem : I have a server action where i made my call to my api using fetch Looks like this 'use server' import 'server-only'; export async function getMyShopsAction(): Promise<Sh..Response> { const url = `${API_URL}/sh...` try { const cookieStore = await cookies(); const authToken = cookieStore.get('auth-store'); So based on the answer i found on the internet i can : 1 - use dynamic = 'force-dynamic' 2 - use noStore() 3 - use dynamic = 'force-dynamic' + revalidate 4 - i got the idea of creating some client component like a middlewear where i would use the cookies ... Then use it in my getMyShopsAction() ... So what do you guys think ? or if anyone has some official docs to solve my problem guys please ! It will be a big help Thank you for reading me and have nice day
Spectacled Caiman
Hey so this error happens because Next js is trying to statically pre render your dashboard page at build time but your server action calls cookies which makes it dynamic!!!! The thing is you actually want this page to be dynamic since you need user specific auth data on every request so the solution is totally fine to use!!!!

Heres what you should do, in your page file for dashboard add export const dynamic = force-dynamic at the top level, this tells Next js to skip static rendering for that ROUTEEE and render it on demand every time!!!! You dont need noStore or a client component middleware workaround, just force dynamic is the cleanest approach for auth protected pages that read cookies!!!! The error will disappear and your page will render correctly with the auth token from cookies on every request!!!! If you want more control you can also use export const revalidate = 0 but force dynamic is simpler for pages that always need fresh user data!!!! This is the official Next js way to handle dynamic data like cookies and its totally expected for dashboard or protected routessss!!!!
Answer
Thank you so much for your help & answer Shrey !
Greater Shearwater
Looking at your function name, I feel like you are trying to fetch inside a Server Action, which you shouldn't do. Server Actions are for mutations (POST requests).

Instead you can just fetch inside your Server Component. Inside the Server Component you can read the cookies and check for the auth status as well. Because you will be using a dynamic API like cookies the route will automatically switch to dynamic rendering at request time.
Oh thank you for your reply Darkstar !
I'm new in using nextjs ! I did not understand your comment at first, cause in my mind they were the same !
Thank you for your great analysis ! I'll fix my components then !
Edit :
But , I'm using my server action getMyShopsAction() inside a server component,
Let me think i'm confused
Okay so my server component should do directly the call without using an action ?
@tensefrogomar Oh thank you for your reply Darkstar ! I'm new in using nextjs ! I did not understand your comment at first, cause in my mind they were the same ! Thank you for your great analysis ! I'll fix my components then ! Edit : But , I'm using my server action getMyShopsAction() inside a server component, Let me think i'm confused Okay so my server component should do directly the call without using an action ?
Greater Shearwater
Yeah, they are not the same.

Server Components are React components that runs only in the server. Their JS code is not sent to the client. So you can do things that you would do in a server environment in those. They can be async components unlike Client Components, so you can call a fetch, await for it, and render some UI using that fetched data or pass those fetched data to Client Components.

Server Actions are basically like an endpoint React and Next.js creates under the hood. So think it of like an API endpoint but for POST requests. Create, update, delete etc.

So the pattern is you use Server Components to fetch data (GET requests) and use Server Actions to create, update and delete data. You could call Server Actions on button clicks but it's more common to use them within a form as a form action.

I suggest you read through these 2 doc pages. They explain everything really well.

https://nextjs.org/docs/app/getting-started/fetching-data
https://nextjs.org/docs/app/getting-started/updating-data
Greater Shearwater
Okay so my server component should do directly the call without using an action ?
Yeah, if it's data fetching, you can directly use fetch inside the Server Component. You can read cookies inside Server Components as well.
Okay okay i understand better now ! okay so it's more of a pattern or a logical separation between those two on how to use them !
But i have a last question
... Nah no more question , all clear, i'll look for some other example to understand better !
Any way thank you so much Darkstar for your big help !
Cuban Crocodile
Hey, sorry to jump in, but it's relevant Darkstar

So my App has

App "use server" > route.ts

Currently, route.ts is doing all GET, PUT and POST api things, everything works.

Does this mean I just move my GET and PUT outside of here?
@Cuban Crocodile Hey, sorry to jump in, but it's relevant Darkstar So my App has `App "use server" > route.ts` Currently, route.ts is doing all GET, PUT and POST api things, everything works. Does this mean I just move my GET and PUT outside of here?
Greater Shearwater
What does your route.ts do? Calling an external API? Calling a DB? Is there something inside the route.ts that you can't do inside Server Components and Server Actions?

For example, if it's just an external fetch call or a DB query, you can do it directly inside the Server Component. So the route handler can be avoided.

And if you need the route handler, then for the GET requests you can directly call it from your Server Component.

Whichever option you chose the GET request shouldn't need to go through a Server Action. Keep it for data mutations, so for POST and PUT as well.
@Greater Shearwater What does your `route.ts` do? Calling an external API? Calling a DB? Is there something inside the `route.ts` that you can't do inside Server Components and Server Actions? For example, if it's just an external fetch call or a DB query, you can do it directly inside the Server Component. So the route handler can be avoided. And if you need the route handler, then for the GET requests you can directly call it from your Server Component. Whichever option you chose the GET request shouldn't need to go through a Server Action. Keep it for data mutations, so for POST and PUT as well.
Cuban Crocodile
thanks Darkstar. I Think i need to read up some more.

TBH there is a lot of similar terminology and I am having a hard time distinguishing between all of it.

I pasted your advice in cursor and it basically moved the GET requests outside my root route.ts, and then create an /api/ folder, which then called the root route.ts

It's confusing for me, imo, when a component > calls an API route > calls a server function
probably just too new and misunderstanding
@Cuban Crocodile thanks Darkstar. I Think i need to read up some more. TBH there is a lot of similar terminology and I am having a hard time distinguishing between all of it. I pasted your advice in cursor and it basically moved the GET requests outside my root route.ts, and then create an /api/ folder, which then called the root route.ts It's confusing for me, imo, when a component > calls an API route > calls a server function
Greater Shearwater
Yeah, it’s a bit hard to tell anything without actually knowing what’s happening inside your route handlers (which is your route.ts) and where you are calling them from.

As I said, if you are using them to just fetch and update data in your database or an external API, you can simply remove the route handlers and do it in Server Components and Server Actions.

I suggest you read through the Getting Started section in the Next.js docs. It covers all these and shows you common patterns used in Next.js. https://nextjs.org/docs/app/getting-started
@Greater Shearwater Yeah, it’s a bit hard to tell anything without actually knowing what’s happening inside your route handlers (which is your route.ts) and where you are calling them from. As I said, if you are using them to just fetch and update data in your database or an external API, you can simply remove the route handlers and do it in Server Components and Server Actions. I suggest you read through the Getting Started section in the Next.js docs. It covers all these and shows you common patterns used in Next.js. https://nextjs.org/docs/app/getting-started
Cuban Crocodile
thanks, i think i've clarified it a bit

So basically, I have one file called xero.ts, it has "use server" and lives in my root directory.

I then call it from my components, which are mainly server components, but the odd use client component.

From what I can tell, a route handler will assign a publicly accesible API folder, for example, app/stripe/route.ts, this is necessary to be public for some reason, such as to receive a public thing, whether a webhook telling my app something, or a oath callback

Is that knowledge correct?
Greater Shearwater
Yeah, that right. That's why I asked what actually happens inside your route handlers and what are calling it.

Again, if it was just your own app calling a fetch or a database, you can avoid the route handler and do it directly inside the Server Components and Server Actions. But yeah for things like webhooks you will need a route handler as it creates public API endpoints other services can call.
Cuban Crocodile
sweet
ty for ur helpo