mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
In a Pages Router app that combines a `basePath`, `next.config.js` `rewrites`, middleware, and a catch-all dynamic route, a client-side `Link` navigation could land on the page with a corrupted `router.query`. Instead of holding the captured route segments, the catch-all param ended up holding the segments of the internal `_next/data/<buildId>/...` URL. Page code that builds further URLs from `router.query` then produced malformed paths and 404s in production. The corruption originated in `getMiddlewareData`, which was passing `nextConfig: undefined` to `getNextPathnameInfo` whenever `__NEXT_HAS_REWRITES` was true. With basePath set, that meant the basePath prefix was never stripped from the data-source URL, so the `/_next/data/` check never matched and the data prefix was left intact. The resulting pathname flowed back into `routeInfo.resolvedAs`, and on catch-all routes the route regex matched it and overwrote `router.query.<param>` with the data-URL segments. The original ternary at this call site (added in #48753) was there to avoid stripping the locale prefix, since `resolveRewrites` needs `as` to keep its locale prefix to match locale-aware rewrite sources. Disabling all of `nextConfig` was too coarse and broke basePath stripping in the process. The fix passes a partial config with only `basePath` and `trailingSlash`, which keeps the locale prefix intact while still letting `getNextPathnameInfo` strip basePath before the data-prefix check. The new `test/e2e/middleware-dynamic-basepath-matcher-rewrites/` fixture is the catch-all + basePath + rewrites + middleware variant of `test/e2e/middleware-dynamic-basepath-matcher/` (#48753's regression test), and asserts that `router.query.path` is preserved across a client-side `Link` navigation.
20 lines
607 B
TypeScript
20 lines
607 B
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
import { retry } from 'next-test-utils'
|
|
|
|
describe('middleware-dynamic-basepath-matcher-rewrites', () => {
|
|
const { next } = nextTestSetup({
|
|
files: __dirname,
|
|
})
|
|
|
|
it('preserves router.query on client-side navigation to a catch-all page', async () => {
|
|
const browser = await next.browser('/docs')
|
|
await browser.elementById('catchall-link').click()
|
|
|
|
await retry(async () => {
|
|
expect(await browser.elementById('page-title').text()).toBe('CatchAll')
|
|
})
|
|
|
|
expect(await browser.elementById('query-path').text()).toBe('["first"]')
|
|
})
|
|
})
|