Skip to content

Commit 028a562

Browse files
committed
fix root page revalidation when redirecting in a server action
1 parent 843332f commit 028a562

File tree

5 files changed

+50
-3
lines changed

5 files changed

+50
-3
lines changed

packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,9 @@ export function serverActionReducer(
225225
[''],
226226
currentTree,
227227
treePatch,
228-
href
228+
redirectLocation
229+
? createHrefFromUrl(redirectLocation)
230+
: state.canonicalUrl
229231
)
230232

231233
if (newTree === null) {

test/e2e/app-dir/parallel-routes-revalidation/app/actions.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
'use server'
2+
import { revalidatePath } from 'next/cache'
23
import { redirect } from 'next/navigation'
34

4-
const data = []
5+
let data = []
56

67
export async function addData(newData: string) {
78
// sleep 1s
@@ -21,3 +22,8 @@ export async function redirectAction() {
2122
await new Promise((res) => setTimeout(res, 1000))
2223
redirect('/')
2324
}
25+
26+
export async function clearData() {
27+
data = []
28+
revalidatePath('/')
29+
}

test/e2e/app-dir/parallel-routes-revalidation/app/page.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Link from 'next/link'
2-
import { getData } from './actions'
2+
import { clearData, getData } from './actions'
33

44
export default async function Home() {
55
const data = await getData()
@@ -14,6 +14,9 @@ export default async function Home() {
1414
<Link href="/redirect-modal">Open Redirect Modal</Link>
1515
<Link href="/detail-page">Intercepted Detail Page</Link>
1616
<div id="random-number">{randomNumber}</div>
17+
<form action={clearData}>
18+
<button id="clear-entries">Clear Entries</button>
19+
</form>
1720
<div>
1821
<h1>Current Data</h1>
1922
<ul id="entries">
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { redirect } from 'next/navigation'
2+
3+
export default function Page() {
4+
return (
5+
<form
6+
action={async () => {
7+
'use server'
8+
redirect('/')
9+
}}
10+
>
11+
<button type="submit">Redirect</button>
12+
</form>
13+
)
14+
}

test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,28 @@ createNextDescribe(
191191
)
192192
})
193193

194+
it('should refresh the correct page when a server action triggers a redirect', async () => {
195+
const browser = await next.browser('/redirect')
196+
await browser.elementByCss('button').click()
197+
198+
await browser.elementByCss("[href='/revalidate-modal']").click()
199+
200+
// clear any entries
201+
await browser.elementById('clear-entries').click()
202+
203+
await retry(async () => {
204+
// confirm there aren't any entries yet
205+
expect((await browser.elementsByCss('#entries li')).length).toBe(0)
206+
})
207+
208+
await browser.elementById('create-entry').click()
209+
210+
await retry(async () => {
211+
// we created an entry and called revalidate, so we should have 1 entry
212+
expect((await browser.elementsByCss('#entries li')).length).toBe(1)
213+
})
214+
})
215+
194216
describe.each([
195217
{ basePath: '/refreshing', label: 'regular', withSearchParams: false },
196218
{ basePath: '/refreshing', label: 'regular', withSearchParams: true },

0 commit comments

Comments
 (0)