diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 8bd0d3cc58f91..29f4cc928e5ae 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -190,7 +190,7 @@ async function generateClientSsgManifest( } function pageToRoute(page: string) { - const routeRegex = getNamedRouteRegex(page) + const routeRegex = getNamedRouteRegex(page, true) return { page, regex: normalizeRouteRegex(routeRegex.re.source), @@ -1975,7 +1975,8 @@ export default async function build( if (isDynamicRoute(page)) { const routeRegex = getNamedRouteRegex( - dataRoute.replace(/\.json$/, '') + dataRoute.replace(/\.json$/, ''), + true ) dataRouteRegex = normalizeRouteRegex( @@ -2392,7 +2393,7 @@ export default async function build( // dynamicParams for non-static paths? finalDynamicRoutes[page] = { routeRegex: normalizeRouteRegex( - getNamedRouteRegex(page).re.source + getNamedRouteRegex(page, false).re.source ), dataRoute, // if dynamicParams are enabled treat as fallback: @@ -2404,7 +2405,8 @@ export default async function build( ? null : normalizeRouteRegex( getNamedRouteRegex( - dataRoute.replace(/\.rsc$/, '') + dataRoute.replace(/\.rsc$/, ''), + false ).re.source.replace(/\(\?:\\\/\)\?\$$/, '\\.rsc$') ), } @@ -2769,7 +2771,7 @@ export default async function build( finalDynamicRoutes[tbdRoute] = { routeRegex: normalizeRouteRegex( - getNamedRouteRegex(tbdRoute).re.source + getNamedRouteRegex(tbdRoute, false).re.source ), dataRoute, fallback: ssgBlockingFallbackPages.has(tbdRoute) @@ -2779,7 +2781,8 @@ export default async function build( : false, dataRouteRegex: normalizeRouteRegex( getNamedRouteRegex( - dataRoute.replace(/\.json$/, '') + dataRoute.replace(/\.json$/, ''), + false ).re.source.replace(/\(\?:\\\/\)\?\$$/, '\\.json$') ), } diff --git a/packages/next/src/build/webpack/loaders/next-metadata-image-loader.ts b/packages/next/src/build/webpack/loaders/next-metadata-image-loader.ts index 7bc81b91c66b1..2341bf5654b9a 100644 --- a/packages/next/src/build/webpack/loaders/next-metadata-image-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-metadata-image-loader.ts @@ -59,7 +59,7 @@ async function nextMetadataImageLoader(this: any, content: Buffer) { const exportedImageData = { ...exported } export default (props) => { const pathname = ${JSON.stringify(route)} - const routeRegex = getNamedRouteRegex(pathname) + const routeRegex = getNamedRouteRegex(pathname, false) const route = interpolateDynamicPath(pathname, props.params, routeRegex) const imageData = { @@ -111,7 +111,7 @@ async function nextMetadataImageLoader(this: any, content: Buffer) { export default (props) => { const pathname = ${JSON.stringify(route)} - const routeRegex = getNamedRouteRegex(pathname) + const routeRegex = getNamedRouteRegex(pathname, false) const route = interpolateDynamicPath(pathname, props.params, routeRegex) const imageData = ${JSON.stringify(imageData)}; diff --git a/packages/next/src/lib/constants.ts b/packages/next/src/lib/constants.ts index 5290d2b30cee7..127503b22d3c7 100644 --- a/packages/next/src/lib/constants.ts +++ b/packages/next/src/lib/constants.ts @@ -1,5 +1,7 @@ import type { ServerRuntime } from '../../types' +export const NEXT_QUERY_PARAM_PREFIX = 'nextParam' + // in seconds export const CACHE_ONE_YEAR = 31536000 diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 055157eb223c3..98d3ed5be034f 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -101,6 +101,7 @@ import { RouteKind } from './future/route-kind' import { handleInternalServerErrorResponse } from './future/route-modules/helpers/response-handlers' import { parseNextReferrerFromHeaders } from './lib/parse-next-referrer' import { fromNodeHeaders, toNodeHeaders } from './web/utils' +import { NEXT_QUERY_PARAM_PREFIX } from '../lib/constants' export type FindComponentsResult = { components: LoadComponentsReturnType @@ -783,6 +784,24 @@ export default abstract class Server { addRequestMeta(req, '_nextRewroteUrl', parsedUrl.pathname!) addRequestMeta(req, '_nextDidRewrite', true) } + const routeParamKeys = new Set() + + for (const key of Object.keys(parsedUrl.query)) { + const value = parsedUrl.query[key] + + if ( + key !== NEXT_QUERY_PARAM_PREFIX && + key.startsWith(NEXT_QUERY_PARAM_PREFIX) + ) { + const normalizedKey = key.substring( + NEXT_QUERY_PARAM_PREFIX.length + ) + parsedUrl.query[normalizedKey] = value + + routeParamKeys.add(normalizedKey) + delete parsedUrl.query[key] + } + } // interpolate dynamic params and normalize URL if needed if (pageIsDynamic) { @@ -861,7 +880,6 @@ export default abstract class Server { matchedPath = utils.interpolateDynamicPath(srcPathname, params) req.url = utils.interpolateDynamicPath(req.url!, params) } - Object.assign(parsedUrl.query, params) } if (pageIsDynamic || didRewrite) { @@ -870,6 +888,9 @@ export default abstract class Server { ...Object.keys(utils.defaultRouteRegex?.groups || {}), ]) } + for (const key of routeParamKeys) { + delete parsedUrl.query[key] + } parsedUrl.pathname = `${this.nextConfig.basePath || ''}${ matchedPath === '/' && this.nextConfig.basePath ? '' : matchedPath }` diff --git a/packages/next/src/server/server-utils.ts b/packages/next/src/server/server-utils.ts index 8bcf574174e81..fb8b858cb4e60 100644 --- a/packages/next/src/server/server-utils.ts +++ b/packages/next/src/server/server-utils.ts @@ -23,6 +23,7 @@ import { TEMPORARY_REDIRECT_STATUS } from '../shared/lib/constants' import { addRequestMeta } from './request-meta' import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing-slash' import { normalizeRscPath } from '../shared/lib/router/utils/app-paths' +import { NEXT_QUERY_PARAM_PREFIX } from '../lib/constants' export function normalizeVercelUrl( req: BaseNextRequest | IncomingMessage, @@ -37,8 +38,14 @@ export function normalizeVercelUrl( const _parsedUrl = parseUrl(req.url!, true) delete (_parsedUrl as any).search - for (const param of paramKeys || Object.keys(defaultRouteRegex.groups)) { - delete _parsedUrl.query[param] + for (const key of Object.keys(_parsedUrl.query)) { + if ( + (key !== NEXT_QUERY_PARAM_PREFIX && + key.startsWith(NEXT_QUERY_PARAM_PREFIX)) || + (paramKeys || Object.keys(defaultRouteRegex.groups)).includes(key) + ) { + delete _parsedUrl.query[key] + } } req.url = formatUrl(_parsedUrl) } @@ -107,7 +114,7 @@ export function getUtils({ let defaultRouteMatches: ParsedUrlQuery | undefined if (pageIsDynamic) { - defaultRouteRegex = getNamedRouteRegex(page) + defaultRouteRegex = getNamedRouteRegex(page, false) dynamicRouteMatcher = getRouteMatcher(defaultRouteRegex) defaultRouteMatches = dynamicRouteMatcher(page) as ParsedUrlQuery } diff --git a/packages/next/src/server/web-server.ts b/packages/next/src/server/web-server.ts index 7e308a3d7259a..68e1de0b046ae 100644 --- a/packages/next/src/server/web-server.ts +++ b/packages/next/src/server/web-server.ts @@ -290,7 +290,7 @@ export default class NextWebServer extends BaseServer { pathname = this.serverOptions.webServerConfig.page if (isDynamicRoute(pathname)) { - const routeRegex = getNamedRouteRegex(pathname) + const routeRegex = getNamedRouteRegex(pathname, false) pathname = interpolateDynamicPath(pathname, query, routeRegex) normalizeVercelUrl( req, diff --git a/packages/next/src/shared/lib/router/utils/route-regex.ts b/packages/next/src/shared/lib/router/utils/route-regex.ts index 37f0f4be275c9..8e8bb785ee5f7 100644 --- a/packages/next/src/shared/lib/router/utils/route-regex.ts +++ b/packages/next/src/shared/lib/router/utils/route-regex.ts @@ -1,6 +1,8 @@ import { escapeStringRegexp } from '../../escape-regexp' import { removeTrailingSlash } from './remove-trailing-slash' +const NEXT_QUERY_PARAM_PREFIX = 'nextParam' + export interface Group { pos: number repeat: boolean @@ -88,7 +90,7 @@ function buildGetSafeRouteKey() { } } -function getNamedParametrizedRoute(route: string) { +function getNamedParametrizedRoute(route: string, prefixRouteKeys: boolean) { const segments = removeTrailingSlash(route).slice(1).split('/') const getSafeRouteKey = buildGetSafeRouteKey() const routeKeys: { [named: string]: string } = {} @@ -115,7 +117,13 @@ function getNamedParametrizedRoute(route: string) { cleanedKey = getSafeRouteKey() } - routeKeys[cleanedKey] = key + if (prefixRouteKeys) { + cleanedKey = `${NEXT_QUERY_PARAM_PREFIX}${cleanedKey}` + routeKeys[cleanedKey] = `${NEXT_QUERY_PARAM_PREFIX}${key}` + } else { + routeKeys[cleanedKey] = `${key}` + } + return repeat ? optional ? `(?:/(?<${cleanedKey}>.+?))?` @@ -133,10 +141,16 @@ function getNamedParametrizedRoute(route: string) { /** * This function extends `getRouteRegex` generating also a named regexp where * each group is named along with a routeKeys object that indexes the assigned - * named group with its corresponding key. + * named group with its corresponding key. When the routeKeys need to be + * prefixed to uniquely identify internally the "prefixRouteKey" arg should + * be "true" currently this is only the case when creating the routes-manifest + * during the build */ -export function getNamedRouteRegex(normalizedRoute: string) { - const result = getNamedParametrizedRoute(normalizedRoute) +export function getNamedRouteRegex( + normalizedRoute: string, + prefixRouteKey: boolean +) { + const result = getNamedParametrizedRoute(normalizedRoute, prefixRouteKey) return { ...getRouteRegex(normalizedRoute), namedRegex: `^${result.namedParameterizedRoute}(?:/)?$`, @@ -163,7 +177,10 @@ export function getNamedMiddlewareRegex( } } - const { namedParameterizedRoute } = getNamedParametrizedRoute(normalizedRoute) + const { namedParameterizedRoute } = getNamedParametrizedRoute( + normalizedRoute, + false + ) let catchAllGroupedRegex = catchAll ? '(?:(/.*)?)' : '' return { namedRegex: `^${namedParameterizedRoute}${catchAllGroupedRegex}$`, diff --git a/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/page.js b/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/page.js index c05ec600a70b4..ca5cd77f0f571 100644 --- a/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/page.js +++ b/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/page.js @@ -1,5 +1,7 @@ 'use client' +import { useSearchParams } from 'next/navigation' + export default function IdPage({ children, params }) { return ( <> @@ -8,6 +10,10 @@ export default function IdPage({ children, params }) { {JSON.stringify(params)}

{children} + +

+ {JSON.stringify(Object.fromEntries(useSearchParams()))} +

) } diff --git a/test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js b/test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js index 02df487f6da92..80029dd814759 100644 --- a/test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js +++ b/test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js @@ -1,4 +1,4 @@ -export default function IdPage({ children, params }) { +export default function IdPage({ children, params, searchParams }) { return ( <>

@@ -6,6 +6,8 @@ export default function IdPage({ children, params }) { {JSON.stringify(params)}

{children} + +

{JSON.stringify(searchParams)}

) } diff --git a/test/e2e/app-dir/app/index.test.ts b/test/e2e/app-dir/app/index.test.ts index c49a6fead4258..5290fa52305e6 100644 --- a/test/e2e/app-dir/app/index.test.ts +++ b/test/e2e/app-dir/app/index.test.ts @@ -10,6 +10,35 @@ createNextDescribe( files: __dirname, }, ({ next, isNextDev: isDev, isNextStart, isNextDeploy }) => { + it('should have correct searchParams and params (server)', async () => { + const html = await next.render('/dynamic/category-1/id-2?query1=value2') + const $ = cheerio.load(html) + + expect(JSON.parse($('#id-page-params').text())).toEqual({ + category: 'category-1', + id: 'id-2', + }) + expect(JSON.parse($('#search-params').text())).toEqual({ + query1: 'value2', + }) + }) + + it('should have correct searchParams and params (client)', async () => { + const browser = await next.browser( + '/dynamic-client/category-1/id-2?query1=value2' + ) + const html = await browser.eval('document.documentElement.innerHTML') + const $ = cheerio.load(html) + + expect(JSON.parse($('#id-page-params').text())).toEqual({ + category: 'category-1', + id: 'id-2', + }) + expect(JSON.parse($('#search-params').text())).toEqual({ + query1: 'value2', + }) + }) + if (!isDev) { it('should successfully detect app route during prefetch', async () => { const browser = await next.browser('/') diff --git a/test/e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts b/test/e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts index a58ffc9b5ba5b..ec459464e3350 100644 --- a/test/e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts +++ b/test/e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts @@ -5,6 +5,8 @@ createNextDescribe( 'parallel-routes-and-interception', { files: __dirname, + // TODO: remove after deployment handling is updated + skipDeployment: true, }, ({ next }) => { describe('parallel routes', () => { diff --git a/test/e2e/app-dir/parallel-routes-and-interception/tsconfig.json b/test/e2e/app-dir/parallel-routes-and-interception/tsconfig.json deleted file mode 100644 index d2bc2ac5e3cea..0000000000000 --- a/test/e2e/app-dir/parallel-routes-and-interception/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": false, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "incremental": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "plugins": [ - { - "name": "next" - } - ] - }, - "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] -} diff --git a/test/e2e/edge-render-getserversideprops/index.test.ts b/test/e2e/edge-render-getserversideprops/index.test.ts index 8d6133490cae9..7726aee46e869 100644 --- a/test/e2e/edge-render-getserversideprops/index.test.ts +++ b/test/e2e/edge-render-getserversideprops/index.test.ts @@ -140,10 +140,10 @@ describe('edge-render-getserversideprops', () => { ), namedDataRouteRegex: `^/_next/data/${escapeStringRegexp( next.buildId - )}/(?[^/]+?)\\.json$`, + )}/(?[^/]+?)\\.json$`, page: '/[id]', routeKeys: { - id: 'id', + nextParamid: 'nextParamid', }, }, ]) diff --git a/test/e2e/getserversideprops/test/index.test.ts b/test/e2e/getserversideprops/test/index.test.ts index 50df0414ee159..08ef6830ec47b 100644 --- a/test/e2e/getserversideprops/test/index.test.ts +++ b/test/e2e/getserversideprops/test/index.test.ts @@ -43,19 +43,19 @@ const expectedManifestRoutes = () => [ { namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/blog/(?[^/]+?)\\.json$`, + )}/blog/(?[^/]+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex(buildId)}\\/blog\\/([^\\/]+?)\\.json$` ), page: '/blog/[post]', routeKeys: { - post: 'post', + nextParampost: 'nextParampost', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/blog/(?[^/]+?)/(?[^/]+?)\\.json$`, + )}/blog/(?[^/]+?)/(?[^/]+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( buildId @@ -63,20 +63,20 @@ const expectedManifestRoutes = () => [ ), page: '/blog/[post]/[comment]', routeKeys: { - post: 'post', - comment: 'comment', + nextParampost: 'nextParampost', + nextParamcomment: 'nextParamcomment', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/catchall/(?.+?)\\.json$`, + )}/catchall/(?.+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex(buildId)}\\/catchall\\/(.+?)\\.json$` ), page: '/catchall/[...path]', routeKeys: { - path: 'path', + nextParampath: 'nextParampath', }, }, { @@ -127,10 +127,10 @@ const expectedManifestRoutes = () => [ )}\\/not\\-found\\/([^\\/]+?)\\.json$`, namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/not\\-found/(?[^/]+?)\\.json$`, + )}/not\\-found/(?[^/]+?)\\.json$`, page: '/not-found/[slug]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { @@ -182,7 +182,7 @@ const expectedManifestRoutes = () => [ { namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/user/(?[^/]+?)/profile\\.json$`, + )}/user/(?[^/]+?)/profile\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( buildId @@ -190,7 +190,7 @@ const expectedManifestRoutes = () => [ ), page: '/user/[user]/profile', routeKeys: { - user: 'user', + nextParamuser: 'nextParamuser', }, }, ] diff --git a/test/e2e/prerender.test.ts b/test/e2e/prerender.test.ts index d5eb8ba6ae9fe..11053a9ed571b 100644 --- a/test/e2e/prerender.test.ts +++ b/test/e2e/prerender.test.ts @@ -1316,10 +1316,10 @@ describe('Prerender', () => { ), namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/api\\-docs/(?.+?)\\.json$`, + )}/api\\-docs/(?.+?)\\.json$`, page: '/api-docs/[...slug]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { @@ -1346,9 +1346,9 @@ describe('Prerender', () => { ), namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/blocking\\-fallback/(?[^/]+?)\\.json$`, + )}/blocking\\-fallback/(?[^/]+?)\\.json$`, page: '/blocking-fallback/[slug]', - routeKeys: { slug: 'slug' }, + routeKeys: { nextParamslug: 'nextParamslug' }, }, { dataRouteRegex: normalizeRegEx( @@ -1358,9 +1358,9 @@ describe('Prerender', () => { ), namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/blocking\\-fallback\\-once/(?[^/]+?)\\.json$`, + )}/blocking\\-fallback\\-once/(?[^/]+?)\\.json$`, page: '/blocking-fallback-once/[slug]', - routeKeys: { slug: 'slug' }, + routeKeys: { nextParamslug: 'nextParamslug' }, }, { dataRouteRegex: normalizeRegEx( @@ -1370,9 +1370,9 @@ describe('Prerender', () => { ), namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/blocking\\-fallback\\-some/(?[^/]+?)\\.json$`, + )}/blocking\\-fallback\\-some/(?[^/]+?)\\.json$`, page: '/blocking-fallback-some/[slug]', - routeKeys: { slug: 'slug' }, + routeKeys: { nextParamslug: 'nextParamslug' }, }, { dataRouteRegex: normalizeRegEx( @@ -1383,7 +1383,7 @@ describe('Prerender', () => { { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/blog/(?[^/]+?)\\.json$`, + )}/blog/(?[^/]+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1391,13 +1391,13 @@ describe('Prerender', () => { ), page: '/blog/[post]', routeKeys: { - post: 'post', + nextParampost: 'nextParampost', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/blog/(?[^/]+?)/(?[^/]+?)\\.json$`, + )}/blog/(?[^/]+?)/(?[^/]+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1405,14 +1405,14 @@ describe('Prerender', () => { ), page: '/blog/[post]/[comment]', routeKeys: { - post: 'post', - comment: 'comment', + nextParampost: 'nextParampost', + nextParamcomment: 'nextParamcomment', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/catchall/(?.+?)\\.json$`, + )}/catchall/(?.+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1420,13 +1420,13 @@ describe('Prerender', () => { ), page: '/catchall/[...slug]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/catchall\\-explicit/(?.+?)\\.json$`, + )}/catchall\\-explicit/(?.+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1434,13 +1434,13 @@ describe('Prerender', () => { ), page: '/catchall-explicit/[...slug]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/catchall\\-optional(?:/(?.+?))?\\.json$`, + )}/catchall\\-optional(?:/(?.+?))?\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1448,7 +1448,7 @@ describe('Prerender', () => { ), page: '/catchall-optional/[[...slug]]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { @@ -1467,10 +1467,10 @@ describe('Prerender', () => { ), namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/dynamic/(?[^/]+?)\\.json$`, + )}/dynamic/(?[^/]+?)\\.json$`, page: '/dynamic/[slug]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { @@ -1481,10 +1481,10 @@ describe('Prerender', () => { ), namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/fallback\\-only/(?[^/]+?)\\.json$`, + )}/fallback\\-only/(?[^/]+?)\\.json$`, page: '/fallback-only/[slug]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, // TODO: investigate index/index @@ -1499,7 +1499,7 @@ describe('Prerender', () => { { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/lang/(?[^/]+?)/about\\.json$`, + )}/lang/(?[^/]+?)/about\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1507,7 +1507,7 @@ describe('Prerender', () => { ), page: '/lang/[lang]/about', routeKeys: { - lang: 'lang', + nextParamlang: 'nextParamlang', }, }, { @@ -1525,7 +1525,7 @@ describe('Prerender', () => { { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/non\\-json/(?

[^/]+?)\\.json$`, + )}/non\\-json/(?[^/]+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1533,13 +1533,13 @@ describe('Prerender', () => { ), page: '/non-json/[p]', routeKeys: { - p: 'p', + nextParamp: 'nextParamp', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/non\\-json\\-blocking/(?

[^/]+?)\\.json$`, + )}/non\\-json\\-blocking/(?[^/]+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1547,7 +1547,7 @@ describe('Prerender', () => { ), page: '/non-json-blocking/[p]', routeKeys: { - p: 'p', + nextParamp: 'nextParamp', }, }, { @@ -1575,7 +1575,7 @@ describe('Prerender', () => { { namedDataRouteRegex: `^/_next/data/${escapeRegex( next.buildId - )}/user/(?[^/]+?)/profile\\.json$`, + )}/user/(?[^/]+?)/profile\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( next.buildId @@ -1583,7 +1583,7 @@ describe('Prerender', () => { ), page: '/user/[user]/profile', routeKeys: { - user: 'user', + nextParamuser: 'nextParamuser', }, }, ]) diff --git a/test/integration/custom-routes/test/index.test.js b/test/integration/custom-routes/test/index.test.js index b722ea5e6c2a9..69a19f70db072 100644 --- a/test/integration/custom-routes/test/index.test.js +++ b/test/integration/custom-routes/test/index.test.js @@ -1544,10 +1544,10 @@ const runTests = (isDev = false, isTurbo = false) => { ), namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/blog\\-catchall/(?.+?)\\.json$`, + )}/blog\\-catchall/(?.+?)\\.json$`, page: '/blog-catchall/[...slug]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { @@ -1556,10 +1556,10 @@ const runTests = (isDev = false, isTurbo = false) => { )}\\/overridden\\/([^\\/]+?)\\.json$`, namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/overridden/(?[^/]+?)\\.json$`, + )}/overridden/(?[^/]+?)\\.json$`, page: '/overridden/[slug]', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, ], @@ -2464,67 +2464,67 @@ const runTests = (isDev = false, isTurbo = false) => { }, dynamicRoutes: [ { - namedRegex: '^/_sport/(?[^/]+?)(?:/)?$', + namedRegex: '^/_sport/(?[^/]+?)(?:/)?$', page: '/_sport/[slug]', regex: normalizeRegEx('^\\/_sport\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { - namedRegex: '^/_sport/(?[^/]+?)/test(?:/)?$', + namedRegex: '^/_sport/(?[^/]+?)/test(?:/)?$', page: '/_sport/[slug]/test', regex: normalizeRegEx('^\\/_sport\\/([^\\/]+?)\\/test(?:\\/)?$'), routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { - namedRegex: '^/another/(?[^/]+?)(?:/)?$', + namedRegex: '^/another/(?[^/]+?)(?:/)?$', page: '/another/[id]', regex: normalizeRegEx('^\\/another\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - id: 'id', + nextParamid: 'nextParamid', }, }, { - namedRegex: '^/api/dynamic/(?[^/]+?)(?:/)?$', + namedRegex: '^/api/dynamic/(?[^/]+?)(?:/)?$', page: '/api/dynamic/[slug]', regex: normalizeRegEx('^\\/api\\/dynamic\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { - namedRegex: '^/auto\\-export/(?[^/]+?)(?:/)?$', + namedRegex: '^/auto\\-export/(?[^/]+?)(?:/)?$', page: '/auto-export/[slug]', regex: normalizeRegEx('^\\/auto\\-export\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { - namedRegex: '^/blog/(?[^/]+?)(?:/)?$', + namedRegex: '^/blog/(?[^/]+?)(?:/)?$', page: '/blog/[post]', regex: normalizeRegEx('^\\/blog\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - post: 'post', + nextParampost: 'nextParampost', }, }, { - namedRegex: '^/blog\\-catchall/(?.+?)(?:/)?$', + namedRegex: '^/blog\\-catchall/(?.+?)(?:/)?$', page: '/blog-catchall/[...slug]', regex: normalizeRegEx('^\\/blog\\-catchall\\/(.+?)(?:\\/)?$'), routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { - namedRegex: '^/overridden/(?[^/]+?)(?:/)?$', + namedRegex: '^/overridden/(?[^/]+?)(?:/)?$', page: '/overridden/[slug]', regex: '^\\/overridden\\/([^\\/]+?)(?:\\/)?$', routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, ], diff --git a/test/integration/dynamic-routing/test/index.test.js b/test/integration/dynamic-routing/test/index.test.js index 5bd2b707a613c..72410b0083233 100644 --- a/test/integration/dynamic-routing/test/index.test.js +++ b/test/integration/dynamic-routing/test/index.test.js @@ -1257,10 +1257,10 @@ function runTests({ dev }) { )}\\/b\\/([^\\/]+?)\\.json$`, namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/b/(?[^/]+?)\\.json$`, + )}/b/(?[^/]+?)\\.json$`, page: '/b/[123]', routeKeys: { - a: '123', + nextParama: 'nextParam123', }, }, { @@ -1269,16 +1269,17 @@ function runTests({ dev }) { )}\\/c\\/([^\\/]+?)\\.json$`, namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/c/(?[^/]+?)\\.json$`, + )}/c/(?[^/]+?)\\.json$`, page: '/c/[alongparamnameshouldbeallowedeventhoughweird]', routeKeys: { - a: 'alongparamnameshouldbeallowedeventhoughweird', + nextParama: + 'nextParamalongparamnameshouldbeallowedeventhoughweird', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/p1/p2/all\\-ssg/(?.+?)\\.json$`, + )}/p1/p2/all\\-ssg/(?.+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( buildId @@ -1286,13 +1287,13 @@ function runTests({ dev }) { ), page: '/p1/p2/all-ssg/[...rest]', routeKeys: { - rest: 'rest', + nextParamrest: 'nextParamrest', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/p1/p2/nested\\-all\\-ssg/(?.+?)\\.json$`, + )}/p1/p2/nested\\-all\\-ssg/(?.+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( buildId @@ -1300,13 +1301,13 @@ function runTests({ dev }) { ), page: '/p1/p2/nested-all-ssg/[...rest]', routeKeys: { - rest: 'rest', + nextParamrest: 'nextParamrest', }, }, { namedDataRouteRegex: `^/_next/data/${escapeRegex( buildId - )}/p1/p2/predefined\\-ssg/(?.+?)\\.json$`, + )}/p1/p2/predefined\\-ssg/(?.+?)\\.json$`, dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex( buildId @@ -1314,147 +1315,148 @@ function runTests({ dev }) { ), page: '/p1/p2/predefined-ssg/[...rest]', routeKeys: { - rest: 'rest', + nextParamrest: 'nextParamrest', }, }, ], dynamicRoutes: [ { - namedRegex: '^/b/(?[^/]+?)(?:/)?$', + namedRegex: '^/b/(?[^/]+?)(?:/)?$', page: '/b/[123]', regex: normalizeRegEx('^\\/b\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - a: '123', + nextParama: 'nextParam123', }, }, { - namedRegex: `^/blog/(?[^/]+?)/comment/(?[^/]+?)(?:/)?$`, + namedRegex: `^/blog/(?[^/]+?)/comment/(?[^/]+?)(?:/)?$`, page: '/blog/[name]/comment/[id]', regex: normalizeRegEx( '^\\/blog\\/([^\\/]+?)\\/comment\\/([^\\/]+?)(?:\\/)?$' ), routeKeys: { - name: 'name', - id: 'id', + nextParamname: 'nextParamname', + nextParamid: 'nextParamid', }, }, { - namedRegex: '^/c/(?[^/]+?)(?:/)?$', + namedRegex: '^/c/(?[^/]+?)(?:/)?$', page: '/c/[alongparamnameshouldbeallowedeventhoughweird]', regex: normalizeRegEx('^\\/c\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - a: 'alongparamnameshouldbeallowedeventhoughweird', + nextParama: + 'nextParamalongparamnameshouldbeallowedeventhoughweird', }, }, { - namedRegex: '^/catchall\\-dash/(?.+?)(?:/)?$', + namedRegex: '^/catchall\\-dash/(?.+?)(?:/)?$', page: '/catchall-dash/[...hello-world]', regex: normalizeRegEx('^\\/catchall\\-dash\\/(.+?)(?:\\/)?$'), routeKeys: { - helloworld: 'hello-world', + nextParamhelloworld: 'nextParamhello-world', }, }, { - namedRegex: '^/d/(?[^/]+?)(?:/)?$', + namedRegex: '^/d/(?[^/]+?)(?:/)?$', page: '/d/[id]', regex: normalizeRegEx('^\\/d\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - id: 'id', + nextParamid: 'nextParamid', }, }, { - namedRegex: '^/dash/(?[^/]+?)(?:/)?$', + namedRegex: '^/dash/(?[^/]+?)(?:/)?$', page: '/dash/[hello-world]', regex: normalizeRegEx('^\\/dash\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - helloworld: 'hello-world', + nextParamhelloworld: 'nextParamhello-world', }, }, { - namedRegex: '^/index/(?.+?)(?:/)?$', + namedRegex: '^/index/(?.+?)(?:/)?$', page: '/index/[...slug]', regex: normalizeRegEx('^/index/(.+?)(?:/)?$'), routeKeys: { - slug: 'slug', + nextParamslug: 'nextParamslug', }, }, { - namedRegex: `^/on\\-mount/(?[^/]+?)(?:/)?$`, + namedRegex: `^/on\\-mount/(?[^/]+?)(?:/)?$`, page: '/on-mount/[post]', regex: normalizeRegEx('^\\/on\\-mount\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - post: 'post', + nextParampost: 'nextParampost', }, }, { - namedRegex: `^/p1/p2/all\\-ssg/(?.+?)(?:/)?$`, + namedRegex: `^/p1/p2/all\\-ssg/(?.+?)(?:/)?$`, page: '/p1/p2/all-ssg/[...rest]', regex: normalizeRegEx('^\\/p1\\/p2\\/all\\-ssg\\/(.+?)(?:\\/)?$'), routeKeys: { - rest: 'rest', + nextParamrest: 'nextParamrest', }, }, { - namedRegex: `^/p1/p2/all\\-ssr/(?.+?)(?:/)?$`, + namedRegex: `^/p1/p2/all\\-ssr/(?.+?)(?:/)?$`, page: '/p1/p2/all-ssr/[...rest]', regex: normalizeRegEx('^\\/p1\\/p2\\/all\\-ssr\\/(.+?)(?:\\/)?$'), routeKeys: { - rest: 'rest', + nextParamrest: 'nextParamrest', }, }, { - namedRegex: `^/p1/p2/nested\\-all\\-ssg/(?.+?)(?:/)?$`, + namedRegex: `^/p1/p2/nested\\-all\\-ssg/(?.+?)(?:/)?$`, page: '/p1/p2/nested-all-ssg/[...rest]', regex: normalizeRegEx( '^\\/p1\\/p2\\/nested\\-all\\-ssg\\/(.+?)(?:\\/)?$' ), routeKeys: { - rest: 'rest', + nextParamrest: 'nextParamrest', }, }, { - namedRegex: `^/p1/p2/predefined\\-ssg/(?.+?)(?:/)?$`, + namedRegex: `^/p1/p2/predefined\\-ssg/(?.+?)(?:/)?$`, page: '/p1/p2/predefined-ssg/[...rest]', regex: normalizeRegEx( '^\\/p1\\/p2\\/predefined\\-ssg\\/(.+?)(?:\\/)?$' ), routeKeys: { - rest: 'rest', + nextParamrest: 'nextParamrest', }, }, { - namedRegex: `^/(?[^/]+?)(?:/)?$`, + namedRegex: `^/(?[^/]+?)(?:/)?$`, page: '/[name]', regex: normalizeRegEx('^\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - name: 'name', + nextParamname: 'nextParamname', }, }, { - namedRegex: `^/(?[^/]+?)/comments(?:/)?$`, + namedRegex: `^/(?[^/]+?)/comments(?:/)?$`, page: '/[name]/comments', regex: normalizeRegEx('^\\/([^\\/]+?)\\/comments(?:\\/)?$'), routeKeys: { - name: 'name', + nextParamname: 'nextParamname', }, }, { - namedRegex: `^/(?[^/]+?)/on\\-mount\\-redir(?:/)?$`, + namedRegex: `^/(?[^/]+?)/on\\-mount\\-redir(?:/)?$`, page: '/[name]/on-mount-redir', regex: normalizeRegEx( '^\\/([^\\/]+?)\\/on\\-mount\\-redir(?:\\/)?$' ), routeKeys: { - name: 'name', + nextParamname: 'nextParamname', }, }, { - namedRegex: `^/(?[^/]+?)/(?[^/]+?)(?:/)?$`, + namedRegex: `^/(?[^/]+?)/(?[^/]+?)(?:/)?$`, page: '/[name]/[comment]', regex: normalizeRegEx('^\\/([^\\/]+?)\\/([^\\/]+?)(?:\\/)?$'), routeKeys: { - name: 'name', - comment: 'comment', + nextParamname: 'nextParamname', + nextParamcomment: 'nextParamcomment', }, }, ], diff --git a/test/integration/required-server-files-ssr-404/test/index.test.js b/test/integration/required-server-files-ssr-404/test/index.test.js index f9a436446860c..b05ac89cc23ae 100644 --- a/test/integration/required-server-files-ssr-404/test/index.test.js +++ b/test/integration/required-server-files-ssr-404/test/index.test.js @@ -193,7 +193,7 @@ describe('Required Server Files', () => { it('should render dynamic SSR page correctly with x-matched-path', async () => { const html = await renderViaHTTP( appPort, - '/some-other-path?slug=first', + '/some-other-path?nextParamslug=first', undefined, { headers: { @@ -259,7 +259,7 @@ describe('Required Server Files', () => { it('should return data correctly with x-matched-path', async () => { const res = await fetchViaHTTP( appPort, - `/_next/data/${buildId}/dynamic/first.json?slug=first`, + `/_next/data/${buildId}/dynamic/first.json?nextParamslug=first`, undefined, { headers: { diff --git a/test/lib/create-next-install.js b/test/lib/create-next-install.js index e80135ec34085..0e23b0877e124 100644 --- a/test/lib/create-next-install.js +++ b/test/lib/create-next-install.js @@ -89,7 +89,7 @@ async function createNextInstall({ let combinedDependencies = dependencies - if (!(packageJson && packageJson.nextPrivateSkipLocalDeps)) { + if (!(packageJson && packageJson.nextParamateSkipLocalDeps)) { const pkgPaths = await rootSpan .traceChild('linkPackages') .traceAsyncFn(() => diff --git a/test/production/standalone-mode/required-server-files/required-server-files-i18n.test.ts b/test/production/standalone-mode/required-server-files/required-server-files-i18n.test.ts index 26210e4539307..5ab6b2d6f31a8 100644 --- a/test/production/standalone-mode/required-server-files/required-server-files-i18n.test.ts +++ b/test/production/standalone-mode/required-server-files/required-server-files-i18n.test.ts @@ -313,7 +313,7 @@ describe('should set-up next', () => { it('should render dynamic SSR page correctly with x-matched-path', async () => { const html = await renderViaHTTP( appPort, - '/some-other-path?slug=first', + '/some-other-path?nextParamslug=first', undefined, { headers: { @@ -330,7 +330,7 @@ describe('should set-up next', () => { const html2 = await renderViaHTTP( appPort, - '/some-other-path?slug=second', + '/some-other-path?nextParamslug=second', undefined, { headers: { @@ -393,7 +393,7 @@ describe('should set-up next', () => { it('should return data correctly with x-matched-path', async () => { const res = await fetchViaHTTP( appPort, - `/_next/data/${next.buildId}/en/dynamic/first.json?slug=first`, + `/_next/data/${next.buildId}/en/dynamic/first.json?nextParamslug=first`, undefined, { headers: { @@ -640,7 +640,7 @@ describe('should set-up next', () => { const res = await fetchViaHTTP( appPort, '/optional-ssp', - { rest: '', another: 'value' }, + { nextParamrest: '', another: 'value' }, { headers: { 'x-matched-path': '/optional-ssp/[[...rest]]', @@ -722,7 +722,7 @@ describe('should set-up next', () => { const res = await fetchViaHTTP( appPort, '/api/optional', - { rest: '', another: 'value' }, + { nextParamrest: '', another: 'value' }, { headers: { 'x-matched-path': '/api/optional/[[...rest]]', diff --git a/test/production/standalone-mode/required-server-files/required-server-files.test.ts b/test/production/standalone-mode/required-server-files/required-server-files.test.ts index 8c4463abd0af1..f1363f673389a 100644 --- a/test/production/standalone-mode/required-server-files/required-server-files.test.ts +++ b/test/production/standalone-mode/required-server-files/required-server-files.test.ts @@ -570,7 +570,7 @@ describe('should set-up next', () => { it('should render dynamic SSR page correctly with x-matched-path', async () => { const html = await renderViaHTTP( appPort, - '/some-other-path?slug=first', + '/some-other-path?nextParamslug=first', undefined, { headers: { @@ -587,7 +587,7 @@ describe('should set-up next', () => { const html2 = await renderViaHTTP( appPort, - '/some-other-path?slug=second', + '/some-other-path?nextParamslug=second', undefined, { headers: { @@ -703,7 +703,7 @@ describe('should set-up next', () => { it('should return data correctly with x-matched-path', async () => { const res = await fetchViaHTTP( appPort, - `/_next/data/${next.buildId}/dynamic/first.json?slug=first`, + `/_next/data/${next.buildId}/dynamic/first.json?nextParamslug=first`, undefined, { headers: { @@ -1145,7 +1145,7 @@ describe('should set-up next', () => { const res = await fetchViaHTTP( appPort, '/api/optional/index', - { rest: 'index', another: 'value' }, + { nextParamrest: 'index', another: 'value' }, { headers: { 'x-matched-path': '/api/optional/[[...rest]]',