From 6061936c139ef601415497ac2cee950862a729e8 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 24 Jun 2024 12:26:41 +0200 Subject: [PATCH 1/2] Fix server action edge redirect with middleware rewrite --- packages/next/src/server/web/adapter.ts | 5 ++- .../app/actions.ts | 11 +++++++ .../app/layout.tsx | 11 +++++++ .../app/redirect/page.tsx | 3 ++ .../app/server-action/_action.ts | 7 ++++ .../app/server-action/edge/page.tsx | 13 ++++++++ .../app/server-action/node/page.tsx | 13 ++++++++ .../middleware.ts | 5 +++ ...ctions-redirect-middleware-rewrite.test.ts | 33 +++++++++++++++++++ 9 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/actions.ts create mode 100644 test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/layout.tsx create mode 100644 test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/redirect/page.tsx create mode 100644 test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/_action.ts create mode 100644 test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/edge/page.tsx create mode 100644 test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/node/page.tsx create mode 100644 test/e2e/app-dir/server-actions-redirect-middleware-rewrite/middleware.ts create mode 100644 test/e2e/app-dir/server-actions-redirect-middleware-rewrite/server-actions-redirect-middleware-rewrite.test.ts diff --git a/packages/next/src/server/web/adapter.ts b/packages/next/src/server/web/adapter.ts index 85e345d3e9783..d8250e0f94ac7 100644 --- a/packages/next/src/server/web/adapter.ts +++ b/packages/next/src/server/web/adapter.ts @@ -91,8 +91,7 @@ export async function adapter( ensureTestApisIntercepted() await ensureInstrumentationRegistered() - // TODO-APP: use explicit marker for this - const isEdgeRendering = typeof self.__BUILD_MANIFEST !== 'undefined' + const isEdgeRendering = process.env.NEXT_RUNTIME === 'edge' const prerenderManifest: PrerenderManifest | undefined = typeof self.__PRERENDER_MANIFEST === 'string' ? JSON.parse(self.__PRERENDER_MANIFEST) @@ -300,7 +299,7 @@ export async function adapter( * a data URL if the request was a data request. */ const rewrite = response?.headers.get('x-middleware-rewrite') - if (response && rewrite) { + if (response && rewrite && !isEdgeRendering) { const rewriteUrl = new NextURL(rewrite, { forceLocale: true, headers: params.request.headers, diff --git a/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/actions.ts b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/actions.ts new file mode 100644 index 0000000000000..c5028a373450d --- /dev/null +++ b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/actions.ts @@ -0,0 +1,11 @@ +'use server' + +import { redirect } from 'next/navigation' + +export async function relativeRedirect() { + return redirect('./subpage') +} + +export async function absoluteRedirect() { + return redirect('/subpage') +} diff --git a/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/layout.tsx b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/layout.tsx new file mode 100644 index 0000000000000..a9fec4d5077d7 --- /dev/null +++ b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/layout.tsx @@ -0,0 +1,11 @@ +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode +}>) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/redirect/page.tsx b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/redirect/page.tsx new file mode 100644 index 0000000000000..d360a9a05703f --- /dev/null +++ b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/redirect/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return
Redirected
+} diff --git a/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/_action.ts b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/_action.ts new file mode 100644 index 0000000000000..60e6f368f47e7 --- /dev/null +++ b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/_action.ts @@ -0,0 +1,7 @@ +'use server' + +import { redirect } from 'next/navigation' + +export const redirectAction = async () => { + redirect('/redirect') +} diff --git a/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/edge/page.tsx b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/edge/page.tsx new file mode 100644 index 0000000000000..90f39aadc1a1c --- /dev/null +++ b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/edge/page.tsx @@ -0,0 +1,13 @@ +'use client' + +import { redirectAction } from '../_action' + +export default function Page() { + return ( +
+ +
+ ) +} + +export const runtime = 'edge' diff --git a/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/node/page.tsx b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/node/page.tsx new file mode 100644 index 0000000000000..94473a1392d96 --- /dev/null +++ b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/app/server-action/node/page.tsx @@ -0,0 +1,13 @@ +'use client' + +import { redirectAction } from '../_action' + +export default function Page() { + return ( +
+ +
+ ) +} + +export const runtime = 'nodejs' diff --git a/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/middleware.ts b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/middleware.ts new file mode 100644 index 0000000000000..f61dbe0a303bb --- /dev/null +++ b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/middleware.ts @@ -0,0 +1,5 @@ +import { NextRequest, NextResponse } from 'next/server' + +export default function middleware(request: NextRequest) { + return NextResponse.rewrite(request.url) +} diff --git a/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/server-actions-redirect-middleware-rewrite.test.ts b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/server-actions-redirect-middleware-rewrite.test.ts new file mode 100644 index 0000000000000..714f49d0516ff --- /dev/null +++ b/test/e2e/app-dir/server-actions-redirect-middleware-rewrite/server-actions-redirect-middleware-rewrite.test.ts @@ -0,0 +1,33 @@ +import { nextTestSetup } from 'e2e-utils' +import { retry } from 'next-test-utils' + +describe('app-dir - server-actions-redirect-middleware-rewrite.test', () => { + const { next } = nextTestSetup({ + files: __dirname, + }) + + it('should redirect correctly in nodejs runtime with middleware rewrite', async () => { + const browser = await next.browser('/server-action/node') + await browser.waitForElementByCss('button').click() + + await retry(async () => { + expect(await browser.waitForElementByCss('#redirected').text()).toBe( + 'Redirected' + ) + }) + expect(await browser.url()).toBe(`${next.url}/redirect`) + }) + + it('should redirect correctly in edge runtime with middleware rewrite', async () => { + const browser = await next.browser('/server-action/edge') + await browser.waitForElementByCss('button').click() + + await retry(async () => { + expect(await browser.waitForElementByCss('#redirected').text()).toBe( + 'Redirected' + ) + + expect(await browser.url()).toBe(`${next.url}/redirect`) + }) + }) +}) From 05b3f7d67f163ba7cb5e3f8e8783b24e6e798f20 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 24 Jun 2024 12:59:44 +0200 Subject: [PATCH 2/2] revert --- packages/next/src/server/web/adapter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/next/src/server/web/adapter.ts b/packages/next/src/server/web/adapter.ts index d8250e0f94ac7..0ad77180cbcdb 100644 --- a/packages/next/src/server/web/adapter.ts +++ b/packages/next/src/server/web/adapter.ts @@ -91,7 +91,8 @@ export async function adapter( ensureTestApisIntercepted() await ensureInstrumentationRegistered() - const isEdgeRendering = process.env.NEXT_RUNTIME === 'edge' + // TODO-APP: use explicit marker for this + const isEdgeRendering = typeof self.__BUILD_MANIFEST !== 'undefined' const prerenderManifest: PrerenderManifest | undefined = typeof self.__PRERENDER_MANIFEST === 'string' ? JSON.parse(self.__PRERENDER_MANIFEST)