From ae177719c3ff0a63d67f5ed951c06b96cf801ac0 Mon Sep 17 00:00:00 2001 From: Dylan Staley <88163+dstaley@users.noreply.github.com> Date: Thu, 9 Jan 2025 11:55:08 -0800 Subject: [PATCH] fix(nextjs): Always use nextUrl to build rewritten URLs (#4856) --- .changeset/brave-steaks-press.md | 5 +++++ packages/nextjs/src/server/clerkMiddleware.ts | 14 +++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 .changeset/brave-steaks-press.md diff --git a/.changeset/brave-steaks-press.md b/.changeset/brave-steaks-press.md new file mode 100644 index 0000000000..25ae3b9e54 --- /dev/null +++ b/.changeset/brave-steaks-press.md @@ -0,0 +1,5 @@ +--- +'@clerk/nextjs': patch +--- + +Always use nextUrl to build rewritten URLs diff --git a/packages/nextjs/src/server/clerkMiddleware.ts b/packages/nextjs/src/server/clerkMiddleware.ts index 8384030fbb..2e7ce11bfd 100644 --- a/packages/nextjs/src/server/clerkMiddleware.ts +++ b/packages/nextjs/src/server/clerkMiddleware.ts @@ -171,7 +171,7 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]) => { ); handlerResult = userHandlerResult || handlerResult; } catch (e: any) { - handlerResult = handleControlFlowErrors(e, clerkRequest, requestState); + handlerResult = handleControlFlowErrors(e, clerkRequest, request, requestState); } // TODO @nikos: we need to make this more generic @@ -314,11 +314,19 @@ const createMiddlewareProtect = ( // especially when copy-pasting code from one place to another. // This function handles the known errors thrown by the APIs described above, // and returns the appropriate response. -const handleControlFlowErrors = (e: any, clerkRequest: ClerkRequest, requestState: RequestState): Response => { +const handleControlFlowErrors = ( + e: any, + clerkRequest: ClerkRequest, + nextRequest: NextRequest, + requestState: RequestState, +): Response => { if (isNextjsNotFoundError(e)) { // Rewrite to a bogus URL to force not found error return setHeader( - NextResponse.rewrite(`${clerkRequest.clerkUrl.origin}/clerk_${Date.now()}`), + // This is an internal rewrite purely to trigger a not found error. We do not want Next.js to think that the + // destination URL is a valid page, so we use `nextRequest.url` as the base for the fake URL, which Next.js + // understands is an internal URL and won't run middleware against the request. + NextResponse.rewrite(new URL(`/clerk_${Date.now()}`, nextRequest.url)), constants.Headers.AuthReason, 'protect-rewrite', );