Skip to content

Commit

Permalink
fix(nextjs): Handle updated PPR error message (#3499)
Browse files Browse the repository at this point in the history
Co-authored-by: Nikos Douvlis <nikosdouvlis@gmail.com>
  • Loading branch information
ceIia and nikosdouvlis authored Jun 5, 2024
1 parent 478c49b commit adb4c53
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
9 changes: 9 additions & 0 deletions .changeset/small-cycles-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@clerk/nextjs': patch
---

Updated the check ran against the error caught by `buildRequestLike()` to re-throw Static Bailout errors thrown by React in the context of PPR (Partial Pre-Rendering), as these errors shouldn't be caught. This change was required as we have been checking the error message itself, but stopped working after the message was changed in a Next.js update a few months ago.

- Breaking PR: https://github.com/vercel/next.js/commit/3008af6b0e7b2c8aadd986bdcbce5bad6c39ccc8#diff-20c354509ae1e93e143d91b67b75e3df592c38b7d1ec6ccf7c4a2f72b32ab17d
- Why PPR errors shouldn't be caught: https://nextjs.org/docs/messages/ppr-caught-error
- Previous fix: https://github.com/clerk/javascript/pull/2518
29 changes: 20 additions & 9 deletions packages/nextjs/src/app-router/server/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import { NextRequest } from 'next/server';

const isPrerenderingBailout = (e: unknown) => {
if (!(e instanceof Error) || !('message' in e)) return false;

const { message } = e;

const lowerCaseInput = message.toLowerCase();
const dynamicServerUsage = lowerCaseInput.includes('dynamic server usage');
const bailOutPrerendering = lowerCaseInput.includes('this page needs to bail out of prerendering');

// note: new error message syntax introduced in next@14.1.1-canary.21
// but we still want to support older versions.
// https://github.com/vercel/next.js/pull/61332 (dynamic-rendering.ts:153)
const routeRegex = /Route .*? needs to bail out of prerendering at this point because it used .*?./;

return routeRegex.test(message) || dynamicServerUsage || bailOutPrerendering;
};

export const buildRequestLike = () => {
try {
// Dynamically import next/headers, otherwise Next12 apps will break
Expand All @@ -8,15 +25,9 @@ export const buildRequestLike = () => {
const { headers } = require('next/headers');
return new NextRequest('https://placeholder.com', { headers: headers() });
} catch (e: any) {
if (
e &&
'message' in e &&
typeof e.message === 'string' &&
(e.message.toLowerCase().includes('Dynamic server usage'.toLowerCase()) ||
e.message.toLowerCase().includes('This page needs to bail out of prerendering'.toLowerCase()))
) {
throw e;
}
// rethrow the error when react throws a prerendering bailout
// https://nextjs.org/docs/messages/ppr-caught-error
if (e && isPrerenderingBailout(e)) throw e;

throw new Error(
`Clerk: auth() and currentUser() are only supported in App Router (/app directory).\nIf you're using /pages, try getAuth() instead.\nOriginal error: ${e}`,
Expand Down

0 comments on commit adb4c53

Please sign in to comment.