Skip to content

Commit

Permalink
Fix parsing params for i18n optional route in minimal mode (vercel#33896
Browse files Browse the repository at this point in the history
)

This fixes our parsing of params with i18n for optional catch-all routes and ensures a regression test catches this case.

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

Fixes: vercel#30631
  • Loading branch information
ijjk authored and natew committed Feb 16, 2022
1 parent a6bc9e6 commit ade162b
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
Expand Up @@ -179,10 +179,11 @@ export function getUtils({
// Simulate a RegExp match from the \`req.url\` input
exec: (str: string) => {
const obj = parseQs(str)
const matchesHasLocale =
i18n && detectedLocale && obj['1'] === detectedLocale

// favor named matches if available
const routeKeyNames = Object.keys(routeKeys || {})

const filterLocaleItem = (val: string | string[]) => {
if (i18n) {
// locale items can be included in route-matches
Expand Down Expand Up @@ -228,8 +229,13 @@ export function getUtils({

return Object.keys(obj).reduce((prev, key) => {
if (!filterLocaleItem(obj[key])) {
let normalizedKey = key

if (matchesHasLocale) {
normalizedKey = parseInt(key, 10) - 1 + ''
}
return Object.assign(prev, {
[key]: obj[key],
[normalizedKey]: obj[key],
})
}
return prev
Expand Down
29 changes: 26 additions & 3 deletions test/production/required-server-files-i18n.test.ts
Expand Up @@ -601,11 +601,12 @@ describe('should set-up next', () => {
it('should normalize optional values correctly for SSG page', async () => {
const res = await fetchViaHTTP(
appPort,
'/optional-ssg',
{ rest: '', another: 'value' },
'/en/optional-ssg/[[...rest]]',
undefined,
{
headers: {
'x-matched-path': '/optional-ssg/[[...rest]]',
'x-matched-path': '/en/optional-ssg/[[...rest]]',
'x-now-route-matches': 'nextLocale=en&1=en',
},
}
)
Expand All @@ -616,6 +617,28 @@ describe('should set-up next', () => {
expect(props.params).toEqual({})
})

it('should normalize optional values correctly for nested optional SSG page', async () => {
const res = await fetchViaHTTP(
appPort,
'/en/[slug]/social/[[...rest]]',
undefined,
{
headers: {
'x-matched-path': '/en/[slug]/social/[[...rest]]',
'x-now-route-matches': 'nextLocale=en&1=en&2=user-123&slug=user-123',
},
}
)

const html = await res.text()
const $ = cheerio.load(html)
const props = JSON.parse($('#props').text())
expect(props.params).toEqual({
slug: 'user-123',
})
expect($('#page').text()).toBe('/[slug]/social/[[...rest]]')
})

it('should normalize optional values correctly for SSG page with encoded slash', async () => {
const res = await fetchViaHTTP(
appPort,
Expand Down
@@ -0,0 +1,25 @@
export const getStaticProps = ({ params }) => {
return {
props: {
random: Math.random(),
params: params || null,
},
revalidate: 1,
}
}

export const getStaticPaths = () => {
return {
paths: [],
fallback: true,
}
}

export default function Page(props) {
return (
<>
<p id="page">/[slug]/social/[[...rest]]</p>
<p id="props">{JSON.stringify(props)}</p>
</>
)
}

0 comments on commit ade162b

Please sign in to comment.