From 5cee06c24e5c88db5ffc782be92996097478d26b Mon Sep 17 00:00:00 2001 From: James Date: Wed, 8 Jan 2025 13:42:29 +0000 Subject: [PATCH] fix: host not included in route handler urls --- .changeset/short-cats-kneel.md | 7 +++++++ examples/api/app/api/request/route.ts | 5 +++++ examples/api/e2e/base.spec.ts | 7 +++++++ .../src/cli/build/open-next/createServerBundle.ts | 3 +-- 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 .changeset/short-cats-kneel.md create mode 100644 examples/api/app/api/request/route.ts diff --git a/.changeset/short-cats-kneel.md b/.changeset/short-cats-kneel.md new file mode 100644 index 00000000..a789d82a --- /dev/null +++ b/.changeset/short-cats-kneel.md @@ -0,0 +1,7 @@ +--- +"@opennextjs/cloudflare": patch +--- + +fix: host not included in route handler urls + +Next.js was unable to re-construct the correct URLs for the request in a route handler due to being unable to retrieve the hostname. This was due to the internal Next.js option `trustHostHeader` being disabled in OpenNext when there is external middleware - this option is needed for the Next.js server in our environment. diff --git a/examples/api/app/api/request/route.ts b/examples/api/app/api/request/route.ts new file mode 100644 index 00000000..41d73393 --- /dev/null +++ b/examples/api/app/api/request/route.ts @@ -0,0 +1,5 @@ +import { NextRequest } from "next/server"; + +export const GET = (request: NextRequest) => { + return new Response(JSON.stringify({ nextUrl: request.nextUrl.href, url: request.url })); +}; diff --git a/examples/api/e2e/base.spec.ts b/examples/api/e2e/base.spec.ts index 2cba2049..60024131 100644 --- a/examples/api/e2e/base.spec.ts +++ b/examples/api/e2e/base.spec.ts @@ -35,3 +35,10 @@ test("sets environment variables from the Next.js env file", async ({ page }) => const res = await page.request.get("/api/env"); await expect(res.json()).resolves.toEqual(expect.objectContaining({ TEST_ENV_VAR: "TEST_VALUE" })); }); + +test("returns correct information about the request from a route handler", async ({ page }) => { + const res = await page.request.get("/api/request"); + // Next.js can fall back to `localhost:3000` or `n` if it doesn't get the host - neither of these are expected. + const expectedURL = expect.stringMatching(/https?:\/\/localhost:(?!3000)\d+\/api\/request/); + await expect(res.json()).resolves.toEqual({ nextUrl: expectedURL, url: expectedURL }); +}); diff --git a/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts b/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts index 3aaec1ff..eb4f4cb5 100644 --- a/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts +++ b/packages/cloudflare/src/cli/build/open-next/createServerBundle.ts @@ -182,8 +182,7 @@ async function generateBundle( target: /core(\/|\\)util\.js/g, deletes: [ ...(disableNextPrebundledReact ? ["requireHooks"] : []), - ...(disableRouting ? ["trustHostHeader"] : []), - ...(!isBefore13413 ? ["requestHandlerHost"] : []), + ...(isBefore13413 ? ["trustHostHeader"] : ["requestHandlerHost"]), ...(isAfter141 ? ["experimentalIncrementalCacheHandler"] : ["stableIncrementalCache"]), ], }),