Error: Dynamic server usage: headers on Next 13.4
Asked Answered
V

4

7

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()
}
Virginavirginal answered 18/5, 2023 at 23:37 Comment(2)
i've exactly the same error but in a different usecase. i'm checking if the token exists in a server component (using 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.Mishear
Yeah so far my solution has been to remove getStaticProps 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 clearlyVirginavirginal
N
10

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.

Nanon answered 6/6, 2023 at 16:38 Comment(0)
T
3

Possible solutions that I found:

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.

Tudela answered 6/2 at 10:30 Comment(1)
Thanks a lot. I have been trying to solve this problem for 2 days and finally, this works for me.Muckworm
C
1

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';
Carbaugh answered 13/6, 2023 at 12:29 Comment(0)
M
0

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).

Mishear answered 19/5, 2023 at 6:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.