Skip to content

Commit

Permalink
Fix app render: escape segment value #42626 (#42823)
Browse files Browse the repository at this point in the history
Fix: #42398

relates to
#42626 (review)

<!--
Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change that you're making:
-->

## Bug

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

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)

Co-authored-by: JJ Kasper <jj@jjsweb.site>
  • Loading branch information
Marcus-Rise and ijjk committed Nov 18, 2022
1 parent 22b16e1 commit 4d2b7e5
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 1 deletion.
8 changes: 7 additions & 1 deletion packages/next/server/app-render.tsx
Expand Up @@ -874,7 +874,13 @@ export async function renderToHTMLOrFlight(
}

const key = segmentParam.param
const value = pathParams[key]
let value = pathParams[key]

if (Array.isArray(value)) {
value = value.map((i) => encodeURIComponent(i))
} else if (typeof value === 'string') {
value = encodeURIComponent(value)
}

if (!value) {
// Handle case where optional catchall does not have a value, e.g. `/dashboard/[...slug]` when requesting `/dashboard`
Expand Down
12 changes: 12 additions & 0 deletions test/production/app-dir-prefetch-non-iso-url/app/[slug]/page.js
@@ -0,0 +1,12 @@
export default function Slug(props) {
return (
<>
<p id="page">/[slug]</p>
<p id="props">{JSON.stringify(props)}</p>
</>
)
}

export function generateStaticParams() {
return [{ slug: 'iso-url' }, { slug: 'кириллица' }]
}
7 changes: 7 additions & 0 deletions test/production/app-dir-prefetch-non-iso-url/app/layout.js
@@ -0,0 +1,7 @@
export default function Layout({ children }) {
return (
<html>
<body>{children}</body>
</html>
)
}
18 changes: 18 additions & 0 deletions test/production/app-dir-prefetch-non-iso-url/app/page.js
@@ -0,0 +1,18 @@
import Link from 'next/link'

export default function Page(props) {
return (
<>
<p id="page">index</p>
<p id="props">{JSON.stringify(props)}</p>
<Link href="/iso-url" id="to-iso">
/iso-url
</Link>
<br />
<Link href="/кириллица" id="to-non-iso">
/кириллица
</Link>
<br />
</>
)
}
48 changes: 48 additions & 0 deletions test/production/app-dir-prefetch-non-iso-url/index.test.ts
@@ -0,0 +1,48 @@
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'test/lib/next-modes/base'
import { join } from 'path'
import { BrowserInterface } from '../../lib/browsers/base'
import webdriver from 'next-webdriver'
import { check } from 'next-test-utils'

describe('app-dir-prefetch-non-iso-url', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: {
'next.config.js': new FileRef(join(__dirname, 'next.config.js')),
app: new FileRef(join(__dirname, 'app')),
},
})
})
afterAll(() => next.destroy())

it('should go to iso url', async () => {
let browser: BrowserInterface

try {
browser = await webdriver(next.appPort, '/')
await browser.elementByCss('#to-iso').click()
await check(() => browser.elementByCss('#page').text(), '/[slug]')
} finally {
if (browser) {
await browser.close()
}
}
})

it('should go to non-iso url', async () => {
let browser: BrowserInterface

try {
browser = await webdriver(next.appPort, '/')
await browser.elementByCss('#to-non-iso').click()
await check(() => browser.elementByCss('#page').text(), '/[slug]')
} finally {
if (browser) {
await browser.close()
}
}
})
})
6 changes: 6 additions & 0 deletions test/production/app-dir-prefetch-non-iso-url/next.config.js
@@ -0,0 +1,6 @@
/** @type {import("next").NextConfig} */
const nextConfig = {
experimental: { appDir: true },
}

module.exports = nextConfig

0 comments on commit 4d2b7e5

Please sign in to comment.