Skip to content

Commit 21a9d59

Browse files
committed
Fix server action edge redirect with middleware rewrite (#67148)
### 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.
1 parent 1b10b13 commit 21a9d59

File tree

9 files changed

+97
-1
lines changed

9 files changed

+97
-1
lines changed

packages/next/src/server/web/adapter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ export async function adapter(
263263
* a data URL if the request was a data request.
264264
*/
265265
const rewrite = response?.headers.get('x-middleware-rewrite')
266-
if (response && rewrite) {
266+
if (response && rewrite && !isEdgeRendering) {
267267
const rewriteUrl = new NextURL(rewrite, {
268268
forceLocale: true,
269269
headers: params.request.headers,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use server'
2+
3+
import { redirect } from 'next/navigation'
4+
5+
export async function relativeRedirect() {
6+
return redirect('./subpage')
7+
}
8+
9+
export async function absoluteRedirect() {
10+
return redirect('/subpage')
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export default function RootLayout({
2+
children,
3+
}: Readonly<{
4+
children: React.ReactNode
5+
}>) {
6+
return (
7+
<html>
8+
<body>{children}</body>
9+
</html>
10+
)
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Page() {
2+
return <div id="redirected">Redirected</div>
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use server'
2+
3+
import { redirect } from 'next/navigation'
4+
5+
export const redirectAction = async () => {
6+
redirect('/redirect')
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
'use client'
2+
3+
import { redirectAction } from '../_action'
4+
5+
export default function Page() {
6+
return (
7+
<form action={redirectAction}>
8+
<button type="submit">Submit</button>
9+
</form>
10+
)
11+
}
12+
13+
export const runtime = 'edge'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
'use client'
2+
3+
import { redirectAction } from '../_action'
4+
5+
export default function Page() {
6+
return (
7+
<form action={redirectAction}>
8+
<button type="submit">Submit</button>
9+
</form>
10+
)
11+
}
12+
13+
export const runtime = 'nodejs'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
3+
export default function middleware(request: NextRequest) {
4+
return NextResponse.rewrite(request.url)
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { nextTestSetup } from 'e2e-utils'
2+
import { retry } from 'next-test-utils'
3+
4+
describe('app-dir - server-actions-redirect-middleware-rewrite.test', () => {
5+
const { next } = nextTestSetup({
6+
files: __dirname,
7+
})
8+
9+
it('should redirect correctly in nodejs runtime with middleware rewrite', async () => {
10+
const browser = await next.browser('/server-action/node')
11+
await browser.waitForElementByCss('button').click()
12+
13+
await retry(async () => {
14+
expect(await browser.waitForElementByCss('#redirected').text()).toBe(
15+
'Redirected'
16+
)
17+
})
18+
expect(await browser.url()).toBe(`${next.url}/redirect`)
19+
})
20+
21+
it('should redirect correctly in edge runtime with middleware rewrite', async () => {
22+
const browser = await next.browser('/server-action/edge')
23+
await browser.waitForElementByCss('button').click()
24+
25+
await retry(async () => {
26+
expect(await browser.waitForElementByCss('#redirected').text()).toBe(
27+
'Redirected'
28+
)
29+
30+
expect(await browser.url()).toBe(`${next.url}/redirect`)
31+
})
32+
})
33+
})

0 commit comments

Comments
 (0)