From 2bab27d1101ad74d3e264a27bb6f012fd68487a5 Mon Sep 17 00:00:00 2001 From: Jacek Date: Sat, 27 Dec 2025 16:16:09 -0600 Subject: [PATCH 1/4] feat(nextjs): Allow PPR with auth() --- packages/nextjs/src/app-router/server/utils.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/nextjs/src/app-router/server/utils.ts b/packages/nextjs/src/app-router/server/utils.ts index 1c6e24a38f4..d31c759b0e9 100644 --- a/packages/nextjs/src/app-router/server/utils.ts +++ b/packages/nextjs/src/app-router/server/utils.ts @@ -21,6 +21,18 @@ export const isPrerenderingBailout = (e: unknown) => { export async function buildRequestLike(): Promise { try { + // Call connection() first to explicitly opt out of prerendering when using Next.js 16 Cache Components + // This prevents "During prerendering, headers() rejects" errors during build + try { + // @ts-expect-error: connection() only exists in Next.js 16+ + const { connection } = await import('next/server'); + if (typeof connection === 'function') { + await connection(); + } + } catch { + // connection() doesn't exist in older Next.js versions, that's fine + } + // Dynamically import next/headers, otherwise Next12 apps will break // @ts-expect-error: Cannot find module 'next/headers' or its corresponding type declarations.ts(2307) const { headers } = await import('next/headers'); From 82d6703cd59c12dff6b41b88e59ccb3c3dca11ab Mon Sep 17 00:00:00 2001 From: Jacek Date: Sat, 27 Dec 2025 16:17:45 -0600 Subject: [PATCH 2/4] wip --- packages/nextjs/src/app-router/server/auth.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/nextjs/src/app-router/server/auth.ts b/packages/nextjs/src/app-router/server/auth.ts index c8e0549e82d..34f6e21d8ba 100644 --- a/packages/nextjs/src/app-router/server/auth.ts +++ b/packages/nextjs/src/app-router/server/auth.ts @@ -71,6 +71,18 @@ export const auth: AuthFn = (async (options?: AuthOptions) => { // eslint-disable-next-line @typescript-eslint/no-require-imports require('server-only'); + // Call connection() first to explicitly opt out of prerendering when using Next.js 16 Cache Components + // This prevents "During prerendering, headers() rejects" errors during build + try { + // @ts-expect-error: connection() only exists in Next.js 16+ + const { connection } = await import('next/server'); + if (typeof connection === 'function') { + await connection(); + } + } catch { + // connection() doesn't exist in older Next.js versions, that's fine + } + const request = await buildRequestLike(); const stepsBasedOnSrcDirectory = async () => { From eba08cd1e9c8055868437498ac30a73aa340b5cb Mon Sep 17 00:00:00 2001 From: Jacek Date: Sat, 27 Dec 2025 21:44:14 -0600 Subject: [PATCH 3/4] fix(@clerk/nextjs): prevent prerendering errors with Next.js 16 Cache Components Call connection() in auth() before accessing headers() to explicitly signal that the route requires runtime data and cannot be prerendered. This fixes build errors when cacheComponents is enabled in next.config.ts. The fix: - Adds connection() call at the start of auth() function - Gracefully handles older Next.js versions where connection() doesn't exist - Properly re-throws prerendering bailout errors for Next.js to handle Fixes prerendering errors like: 'During prerendering, headers() rejects when the prerender is complete' --- .changeset/silent-streets-rest.md | 5 +++++ packages/nextjs/src/app-router/server/auth.ts | 9 +++++++-- packages/nextjs/src/app-router/server/utils.ts | 12 ------------ 3 files changed, 12 insertions(+), 14 deletions(-) create mode 100644 .changeset/silent-streets-rest.md diff --git a/.changeset/silent-streets-rest.md b/.changeset/silent-streets-rest.md new file mode 100644 index 00000000000..ecf73d93b31 --- /dev/null +++ b/.changeset/silent-streets-rest.md @@ -0,0 +1,5 @@ +--- +'@clerk/nextjs': patch +--- + +Fix prerendering errors when using `auth()` with Next.js 16 Cache Components. diff --git a/packages/nextjs/src/app-router/server/auth.ts b/packages/nextjs/src/app-router/server/auth.ts index 34f6e21d8ba..cf08370dc65 100644 --- a/packages/nextjs/src/app-router/server/auth.ts +++ b/packages/nextjs/src/app-router/server/auth.ts @@ -79,8 +79,13 @@ export const auth: AuthFn = (async (options?: AuthOptions) => { if (typeof connection === 'function') { await connection(); } - } catch { - // connection() doesn't exist in older Next.js versions, that's fine + } catch (e) { + // If this is a prerendering bailout, re-throw it + const { isPrerenderingBailout } = await import('./utils.js'); + if (isPrerenderingBailout(e)) { + throw e; + } + // Otherwise connection() doesn't exist in older Next.js versions, that's fine } const request = await buildRequestLike(); diff --git a/packages/nextjs/src/app-router/server/utils.ts b/packages/nextjs/src/app-router/server/utils.ts index d31c759b0e9..1c6e24a38f4 100644 --- a/packages/nextjs/src/app-router/server/utils.ts +++ b/packages/nextjs/src/app-router/server/utils.ts @@ -21,18 +21,6 @@ export const isPrerenderingBailout = (e: unknown) => { export async function buildRequestLike(): Promise { try { - // Call connection() first to explicitly opt out of prerendering when using Next.js 16 Cache Components - // This prevents "During prerendering, headers() rejects" errors during build - try { - // @ts-expect-error: connection() only exists in Next.js 16+ - const { connection } = await import('next/server'); - if (typeof connection === 'function') { - await connection(); - } - } catch { - // connection() doesn't exist in older Next.js versions, that's fine - } - // Dynamically import next/headers, otherwise Next12 apps will break // @ts-expect-error: Cannot find module 'next/headers' or its corresponding type declarations.ts(2307) const { headers } = await import('next/headers'); From a752d33a536a15f189e5628b66014b8473da2684 Mon Sep 17 00:00:00 2001 From: Jacek Date: Sun, 28 Dec 2025 19:50:42 -0600 Subject: [PATCH 4/4] wip --- packages/nextjs/src/app-router/server/auth.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nextjs/src/app-router/server/auth.ts b/packages/nextjs/src/app-router/server/auth.ts index cf08370dc65..0342e3c4b0f 100644 --- a/packages/nextjs/src/app-router/server/auth.ts +++ b/packages/nextjs/src/app-router/server/auth.ts @@ -79,11 +79,11 @@ export const auth: AuthFn = (async (options?: AuthOptions) => { if (typeof connection === 'function') { await connection(); } - } catch (e) { + } catch (error) { // If this is a prerendering bailout, re-throw it const { isPrerenderingBailout } = await import('./utils.js'); - if (isPrerenderingBailout(e)) { - throw e; + if (isPrerenderingBailout(error)) { + throw error; } // Otherwise connection() doesn't exist in older Next.js versions, that's fine }