Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: Dynamic server usage: headers on Next 13.4

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-auths 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()
}
like image 204
Dan Castrillo Avatar asked Jun 10 '26 18:06

Dan Castrillo


2 Answers

Add

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.

like image 114
Rookie Avatar answered Jun 12 '26 07:06

Rookie


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/or headers 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.

like image 20
Jecrs687 Avatar answered Jun 12 '26 07:06

Jecrs687