Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Update search params/route params handling on deploy
  • Loading branch information
ijjk committed Apr 4, 2023
commit dd781042a2a1e034e635aba5df1d294e5d488cb7
5 changes: 3 additions & 2 deletions packages/next/src/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ function generateClientSsgManifest(
}

function pageToRoute(page: string) {
const routeRegex = getNamedRouteRegex(page)
const routeRegex = getNamedRouteRegex(page, true)
return {
page,
regex: normalizeRouteRegex(routeRegex.re.source),
Expand Down Expand Up @@ -2116,7 +2116,8 @@ export default async function build(

if (isDynamicRoute(page)) {
const routeRegex = getNamedRouteRegex(
dataRoute.replace(/\.json$/, '')
dataRoute.replace(/\.json$/, ''),
true
)

dataRouteRegex = normalizeRouteRegex(
Expand Down
2 changes: 2 additions & 0 deletions packages/next/src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { ServerRuntime } from '../../types'

export const NEXT_QUERY_PARAM_PREFIX = `nextPriv`

// in seconds
export const CACHE_ONE_YEAR = 31536000

Expand Down
20 changes: 16 additions & 4 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -786,9 +787,21 @@ export default abstract class Server<ServerOptions extends Options = Options> {
if (pageIsDynamic) {
let params: ParsedUrlQuery | false = {}

let paramsResult = utils.normalizeDynamicRouteParams(
parsedUrl.query
)
const queryRouteParams: Record<string, string | string[]> = {}

for (const key of Object.keys(parsedUrl.query)) {
const value = parsedUrl.query[key]

if (key.startsWith(NEXT_QUERY_PARAM_PREFIX) && value) {
queryRouteParams[
key.substring(NEXT_QUERY_PARAM_PREFIX.length)
] = value
delete parsedUrl.query[key]
}
}

let paramsResult =
utils.normalizeDynamicRouteParams(queryRouteParams)

// for prerendered ISR paths we attempt parsing the route
// params from the URL directly as route-matches may not
Expand Down Expand Up @@ -859,7 +872,6 @@ export default abstract class Server<ServerOptions extends Options = Options> {
matchedPath = utils.interpolateDynamicPath(srcPathname, params)
req.url = utils.interpolateDynamicPath(req.url!, params)
}
Object.assign(parsedUrl.query, params)
}

if (pageIsDynamic || didRewrite) {
Expand Down
18 changes: 14 additions & 4 deletions packages/next/src/shared/lib/router/utils/route-regex.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { NEXT_QUERY_PARAM_PREFIX } from '../../../../lib/constants'
import { escapeStringRegexp } from '../../escape-regexp'
import { removeTrailingSlash } from './remove-trailing-slash'

Expand Down Expand Up @@ -88,7 +89,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 } = {}
Expand All @@ -115,7 +116,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}>.+?))?`
Expand All @@ -135,8 +142,11 @@ function getNamedParametrizedRoute(route: string) {
* each group is named along with a routeKeys object that indexes the assigned
* named group with its corresponding key.
*/
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}(?:/)?$`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use client'

import { useSearchParams } from 'next/navigation'

export default function IdPage({ children, params }) {
return (
<>
Expand All @@ -8,6 +10,10 @@ export default function IdPage({ children, params }) {
<span id="id-page-params">{JSON.stringify(params)}</span>
</p>
{children}

<p id="search-params">
{JSON.stringify(Object.fromEntries(useSearchParams()))}
</p>
</>
)
}
4 changes: 3 additions & 1 deletion test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export default function IdPage({ children, params }) {
export default function IdPage({ children, params, searchParams }) {
return (
<>
<p>
Id Page. Params:{' '}
<span id="id-page-params">{JSON.stringify(params)}</span>
</p>
{children}

<p id="search-params">{JSON.stringify(searchParams)}</p>
</>
)
}
29 changes: 29 additions & 0 deletions test/e2e/app-dir/app/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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('/')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ createNextDescribe(
'parallel-routes-and-interception',
{
files: __dirname,
// TODO: remove after deployment handling is updated
skipDeployment: true,
},
({ next }) => {
describe('parallel routes', () => {
Expand Down
24 changes: 0 additions & 24 deletions test/e2e/app-dir/parallel-routes-and-interception/tsconfig.json

This file was deleted.

2 changes: 1 addition & 1 deletion test/e2e/edge-render-getserversideprops/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ describe('edge-render-getserversideprops', () => {
)}/(?<id>[^/]+?)\\.json$`,
page: '/[id]',
routeKeys: {
id: 'id',
nextPrivid: 'nextPrivid',
},
},
])
Expand Down
12 changes: 6 additions & 6 deletions test/e2e/getserversideprops/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const expectedManifestRoutes = () => [
),
page: '/blog/[post]',
routeKeys: {
post: 'post',
nextPrivpost: 'nextPrivpost',
},
},
{
Expand All @@ -63,8 +63,8 @@ const expectedManifestRoutes = () => [
),
page: '/blog/[post]/[comment]',
routeKeys: {
post: 'post',
comment: 'comment',
nextPrivpost: 'nextPrivpost',
nextPrivcomment: 'nextPrivcomment',
},
},
{
Expand All @@ -76,7 +76,7 @@ const expectedManifestRoutes = () => [
),
page: '/catchall/[...path]',
routeKeys: {
path: 'path',
nextPrivpath: 'nextPrivpath',
},
},
{
Expand Down Expand Up @@ -130,7 +130,7 @@ const expectedManifestRoutes = () => [
)}/not\\-found/(?<slug>[^/]+?)\\.json$`,
page: '/not-found/[slug]',
routeKeys: {
slug: 'slug',
nextPrivslug: 'nextPrivslug',
},
},
{
Expand Down Expand Up @@ -190,7 +190,7 @@ const expectedManifestRoutes = () => [
),
page: '/user/[user]/profile',
routeKeys: {
user: 'user',
nextPrivuser: 'nextPrivuser',
},
},
]
Expand Down
Loading