Skip to content

Commit

Permalink
Fix server action edge redirect with middleware rewrite (#67148)
Browse files Browse the repository at this point in the history
### What

Add isEdgeRendering check condition for rewrite logic in edge adpator 

Fixes #66837 
Closes NEXT-3545

### Why

From headers `x-middleware-rewrite`, it's still relative url `/rewrite`,
reconstructing the url will lead to crash as it doesn't contain host.
  • Loading branch information
huozhi committed Jul 9, 2024
1 parent 1b10b13 commit 21a9d59
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/next/src/server/web/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html>
<body>{children}</body>
</html>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Page() {
return <div id="redirected">Redirected</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use server'

import { redirect } from 'next/navigation'

export const redirectAction = async () => {
redirect('/redirect')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client'

import { redirectAction } from '../_action'

export default function Page() {
return (
<form action={redirectAction}>
<button type="submit">Submit</button>
</form>
)
}

export const runtime = 'edge'
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client'

import { redirectAction } from '../_action'

export default function Page() {
return (
<form action={redirectAction}>
<button type="submit">Submit</button>
</form>
)
}

export const runtime = 'nodejs'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { NextRequest, NextResponse } from 'next/server'

export default function middleware(request: NextRequest) {
return NextResponse.rewrite(request.url)
}
Original file line number Diff line number Diff line change
@@ -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`)
})
})
})

0 comments on commit 21a9d59

Please sign in to comment.