This is the function generating the error. It's a simple function to get the token from the session
4 |
5 | export async function getUserToken() {
> 6 | const session = await getServerSession(authOptions)
| ^
7 |
8 | return session?.user?.token
9 | }
I've been struggling for a couple days trying to figure out what is the issue. So far I have managed to isolate it to layout
& page
RSC that try to make us of next-auth
s getServerSession
. I need to be able to pass the session to make request on my backend and whenever I try to populate a client component with api calls that need the session the error is thrown.
Any insights or recommended workaround available?
Here is the main layout that needs the request to fill the TeamSwitcher
export default async function RootLayout({ children, params: { lng } }: Props) {
const clients = await getClients()
return (
<>
<div className="flex flex-col">
<div className="border-b">
<div className="flex h-16 items-center px-4">
{/* @ts-expect-error Server Component */}
<MainNav
lng={lng}
title={siteConfig.name}
items={siteConfig.mainNav}
/>
<div className="ml-auto flex items-center space-x-4">
<TeamSwitcher clients={clients} />
{/* @ts-expect-error Server Component */}
<UserNav lng={lng} user={user} />
</div>
</div>
</div>
{children}
</div>
</>
)
}
This is the api call, everything pretty straightforward
export async function getClients(): Promise<Client[]> {
const token = await getUserToken()
if (!token) throw Error("Missing token for request")
return await api
.headers({
accept: "application/json",
token,
})
.get("/clients")
.json()
}
This is the function generating the error. It's a simple function to get the token from the session
4 |
5 | export async function getUserToken() {
> 6 | const session = await getServerSession(authOptions)
| ^
7 |
8 | return session?.user?.token
9 | }
I've been struggling for a couple days trying to figure out what is the issue. So far I have managed to isolate it to layout
& page
RSC that try to make us of next-auth
s getServerSession
. I need to be able to pass the session to make request on my backend and whenever I try to populate a client component with api calls that need the session the error is thrown.
Any insights or recommended workaround available?
Here is the main layout that needs the request to fill the TeamSwitcher
export default async function RootLayout({ children, params: { lng } }: Props) {
const clients = await getClients()
return (
<>
<div className="flex flex-col">
<div className="border-b">
<div className="flex h-16 items-center px-4">
{/* @ts-expect-error Server Component */}
<MainNav
lng={lng}
title={siteConfig.name}
items={siteConfig.mainNav}
/>
<div className="ml-auto flex items-center space-x-4">
<TeamSwitcher clients={clients} />
{/* @ts-expect-error Server Component */}
<UserNav lng={lng} user={user} />
</div>
</div>
</div>
{children}
</div>
</>
)
}
This is the api call, everything pretty straightforward
export async function getClients(): Promise<Client[]> {
const token = await getUserToken()
if (!token) throw Error("Missing token for request")
return await api
.headers({
accept: "application/json",
token,
})
.get("/clients")
.json()
}
Share
Improve this question
asked May 18, 2023 at 23:37
Dan CastrilloDan Castrillo
811 gold badge1 silver badge4 bronze badges
2
|
4 Answers
Reset to default 12Add
export const dynamic = "force-dynamic"
to where you getServerSession, Page, Layout, or Route Handler。
If you are using this api directly and not in the Route Hander, then you need to add the above code to every page that calls it, whereas if you call it from within a component it will not work according to the documentation. So if you need to use it multiple times then Route Hander is a better choice.
Office doc
Server rendering usually happens in one place, so fetching data associated with a user needs to be known to be dynamic.
Dynamic routes occur after fetching some data, Next cannot directly generate the corresponding page or content, so the same needs to be specified dynamically.
Possible solutions that I found:
export const dynamic = "force-dynamic"
export const revalidate = 0
- insert
"use server"
on the top of the file
But, none of those solutions worked for me, after some time I discovered that if the cookie or headers are called inside a try-catch it will generate this error.
Solutions:
- put the calling of the
cookie
and/orheaders
functions outside of the try-catch
Updates:
2023-02-12
Some people use libraries (such as supabase) that get cookies in the background, and it is necessary to put some callers outside try-catch to avoid this issue also.
I've found I get this error when using these functions with static generation - and only while using the dev server, not sure if that's what you're experiencing.
If you're having trouble only with the dev server but still want to statically generate your pages for production (my case) you can add the following to any routes that use generateStaticParams AND call these functions:
// what used to be export function generateStaticParams
function staticParams(){
...
}
// fix "dynamic server usage" errors in dev mode by turning off static generation and forcing dynamic rendering
export const generateStaticParams = process.env.NODE_ENV === "production" ? staticParams : undefined;
export const dynamic = process.env.NODE_ENV === "production" ? 'auto' : 'force-dynamic';
This is probably not the answer you're looking for, but for some reason i had the same issue (see the comment on your post).
I've found a way to bypass this. It's not ideal, but kudos to https://github.com/vercel/next.js/issues/48979#issuecomment-1539961418 who points out https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
From the error stack I had, I could see the same error as yours, but also something earlier mentioning "static rendering".
You can add export const dynamic = 'force-dynamic';
to avoid static pre-rendering at build, which should probably do the trick (it did for me).
getServerSession
) to perform redirections (index to sign-in if not signed, etc). also confused by the error overall, i've no idea why it breaks. – y_nk Commented May 19, 2023 at 6:11getStaticProps
but I'm still not sure I understand the issue. Seems to me that is related to static to dynamic rendering but I can't find any documentation that explains it very clearly – Dan Castrillo Commented May 20, 2023 at 0:41