mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
### What When calling `revalidatePath` or `revalidateTag` in a server action for an intercepted route with dynamic segments, the page would do a full browser refresh. ### Why When constructing rewrites for interception routes, the route params leading up to the interception route are "voided" with a `__NEXT_EMPTY_PARAM__` demarcation. When it comes time to look up the values for these dynamic segments, since the params aren't going to be part of the URL, they get matched via `FlightRouterState` ([ref](https://github.com/vercel/next.js/blob/d67d658ce7396c4b6be1b724be5f45763d5a1803/packages/next/src/server/app-render/app-render.tsx#L153-L201)). The `shouldProvideFlightRouterState` variable only passes it through for RSC requests; however, since the server action will perform the action & return the flight data in a single pass, that means the updated tree from the server action isn't going to receive the `FlightRouterState` when constructing the new tree. This means the old tree will have a `["locale", "en", "d"]` segment, and the new tree from the server action will have `"[locale]"`. When the router detects this kind of segment mismatch, it assumes the user navigated to a new root layout, and triggers an MPA navigation. ### How This unconditionally provides the `FlightRouterState` to `makeGetDynamicParamFromSegment` so that it can properly extract dynamic params for interception routes. We currently enforce interception routes to be dynamic due to this `FlightRouterState` dependency. Fixes #59796 Closes NEXT-2079
46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
import { retry } from 'next-test-utils'
|
|
|
|
describe('dynamic-interception-route-revalidate', () => {
|
|
const { next } = nextTestSetup({
|
|
files: __dirname,
|
|
})
|
|
|
|
it('should refresh the dynamic intercepted route when the interception route is revalidated', async () => {
|
|
const browser = await next.browser('/en')
|
|
|
|
// trigger the interception
|
|
await browser.elementByCss("[href='/en/photos/1/view']").click()
|
|
|
|
// verify we're on the intercepted page
|
|
await browser.waitForElementByCss('#intercepted-page')
|
|
|
|
expect(await browser.elementByCss('h2').text()).toBe('Photo Id: 1')
|
|
|
|
// trigger the revalidate
|
|
await browser.elementByCss('button').click()
|
|
|
|
// make sure the loading state fired
|
|
await browser.waitForElementByCss('#loading')
|
|
|
|
// verify that we get a result from the server action
|
|
await retry(async () => {
|
|
const result = await browser.elementByCss('#result').text()
|
|
expect(result).toMatch(/^Result: 0(\.\d+)?$/)
|
|
})
|
|
|
|
// make sure we're still on the intercepted page
|
|
expect(await browser.hasElementByCssSelector('#intercepted-page')).toBe(
|
|
true
|
|
)
|
|
|
|
// refresh the page to get the full (non-intercepted) page
|
|
await browser.refresh()
|
|
|
|
expect(await browser.hasElementByCssSelector('#intercepted-page')).toBe(
|
|
false
|
|
)
|
|
expect(await browser.hasElementByCssSelector('#full-page')).toBe(true)
|
|
})
|
|
})
|