diff --git a/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts index 7d8e314b848ad1..4784cfbdee5f74 100644 --- a/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts @@ -225,7 +225,9 @@ export function serverActionReducer( [''], currentTree, treePatch, - href + redirectLocation + ? createHrefFromUrl(redirectLocation) + : state.canonicalUrl ) if (newTree === null) { diff --git a/test/e2e/app-dir/parallel-routes-revalidation/app/redirect/page.tsx b/test/e2e/app-dir/parallel-routes-revalidation/app/redirect/page.tsx new file mode 100644 index 00000000000000..f451ae9b3b5bca --- /dev/null +++ b/test/e2e/app-dir/parallel-routes-revalidation/app/redirect/page.tsx @@ -0,0 +1,14 @@ +import { redirect } from 'next/navigation' + +export default function Page() { + return ( +
+ ) +} diff --git a/test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts b/test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts index 80ce5e68aa2524..103a9edee36c39 100644 --- a/test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts +++ b/test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts @@ -191,6 +191,25 @@ createNextDescribe( ) }) + it('should refresh the correct page when a server action triggers a redirect', async () => { + const browser = await next.browser('/redirect') + await browser.elementByCss('button').click() + + await browser.elementByCss("[href='/revalidate-modal']").click() + + await retry(async () => { + // confirm there aren't any entries yet + expect((await browser.elementsByCss('#entries li')).length).toBe(0) + }) + + await browser.elementById('create-entry').click() + + await retry(async () => { + // we created an entry and called revalidate, so we should have 1 entry + expect((await browser.elementsByCss('#entries li')).length).toBe(1) + }) + }) + describe.each([ { basePath: '/refreshing', label: 'regular', withSearchParams: false }, { basePath: '/refreshing', label: 'regular', withSearchParams: true },