Skip to content

Commit 4006812

Browse files
committed
Update experimental skipTrailingSlashRedirect handling
1 parent be75d09 commit 4006812

File tree

4 files changed

+56
-1
lines changed

4 files changed

+56
-1
lines changed

packages/next/build/webpack-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ export function getDefineEnv({
161161
'process.env.__NEXT_ALLOW_MIDDLEWARE_RESPONSE_BODY': JSON.stringify(
162162
config.experimental.allowMiddlewareResponseBody
163163
),
164+
'process.env.__NEXT_MANUAL_TRAILING_SLASH': JSON.stringify(
165+
config.experimental?.skipTrailingSlashRedirect
166+
),
164167
'process.env.__NEXT_CROSS_ORIGIN': JSON.stringify(config.crossOrigin),
165168
'process.browser': JSON.stringify(isClient),
166169
'process.env.__NEXT_TEST_MODE': JSON.stringify(

packages/next/client/normalize-trailing-slash.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { parsePath } from '../shared/lib/router/utils/parse-path'
66
* in `next.config.js`.
77
*/
88
export const normalizePathTrailingSlash = (path: string) => {
9-
if (!path.startsWith('/')) {
9+
if (!path.startsWith('/') || process.env.__NEXT_MANUAL_TRAILING_SLASH) {
1010
return path
1111
}
1212

test/e2e/skip-trailing-slash-redirect/app/pages/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ export default function Page(props) {
88
to another
99
</Link>
1010
<br />
11+
<Link href="/another/" id="to-another-with-slash">
12+
to another
13+
</Link>
14+
<br />
1115
<Link href="/blog/first" id="to-blog-first">
1216
to /blog/first
1317
</Link>

test/e2e/skip-trailing-slash-redirect/index.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,54 @@ describe('skip-trailing-slash-redirect', () => {
158158
expect(await res.text()).toContain('another page')
159159
})
160160

161+
it('should not apply trailing slash to links on client', async () => {
162+
const browser = await webdriver(next.url, '/')
163+
await browser.eval('window.beforeNav = 1')
164+
165+
expect(
166+
new URL(
167+
await browser.elementByCss('#to-another').getAttribute('href'),
168+
'http://n'
169+
).pathname
170+
).toBe('/another')
171+
172+
await browser.elementByCss('#to-another').click()
173+
await browser.waitForElementByCss('#another')
174+
175+
expect(await browser.eval('window.location.pathname')).toBe('/another')
176+
177+
await browser.back().waitForElementByCss('#to-another')
178+
179+
expect(
180+
new URL(
181+
await browser
182+
.elementByCss('#to-another-with-slash')
183+
.getAttribute('href'),
184+
'http://n'
185+
).pathname
186+
).toBe('/another/')
187+
188+
await browser.elementByCss('#to-another-with-slash').click()
189+
await browser.waitForElementByCss('#another')
190+
191+
expect(await browser.eval('window.location.pathname')).toBe('/another/')
192+
193+
await browser.back().waitForElementByCss('#to-another')
194+
expect(await browser.eval('window.beforeNav')).toBe(1)
195+
})
196+
197+
it('should not apply trailing slash on load on client', async () => {
198+
let browser = await webdriver(next.url, '/another')
199+
await check(() => browser.eval('next.router.isReady ? "yes": "no"'), 'yes')
200+
201+
expect(await browser.eval('location.pathname')).toBe('/another')
202+
203+
browser = await webdriver(next.url, '/another/')
204+
await check(() => browser.eval('next.router.isReady ? "yes": "no"'), 'yes')
205+
206+
expect(await browser.eval('location.pathname')).toBe('/another/')
207+
})
208+
161209
it('should not apply trailing slash redirect (with slash)', async () => {
162210
const res = await fetchViaHTTP(next.url, '/another/', undefined, {
163211
redirect: 'manual',

0 commit comments

Comments
 (0)