Skip to content

Commit

Permalink
Prefix basePath in navigate and prefix methods in app router (#45771)
Browse files Browse the repository at this point in the history
Closes #41824.

## Bug

- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/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`
- [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) 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`](https://github.com/vercel/next.js/blob/canary/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)
  • Loading branch information
shuding committed Feb 10, 2023
1 parent be5fd6c commit 1c5983f
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 4 deletions.
11 changes: 7 additions & 4 deletions packages/next/src/client/components/app-router.tsx
Expand Up @@ -37,6 +37,7 @@ import {
} from './router-reducer/create-initial-router-state'
import { fetchServerResponse } from './router-reducer/fetch-server-response'
import { isBot } from '../../shared/lib/router/utils/is-bot'
import { addBasePath } from '../add-base-path'

// Ensure the initialParallelRoutes are not combined because of double-rendering in the browser with Strict Mode.
let initialParallelRoutes: CacheNode['parallelRoutes'] =
Expand Down Expand Up @@ -189,7 +190,7 @@ function Router({
navigateType: 'push' | 'replace',
forceOptimisticNavigation: boolean
) => {
const url = new URL(href, location.origin)
const url = new URL(addBasePath(href), location.origin)

return dispatch({
type: ACTION_NAVIGATE,
Expand All @@ -212,15 +213,17 @@ function Router({
back: () => window.history.back(),
forward: () => window.history.forward(),
prefetch: async (href) => {
const hrefWithBasePath = addBasePath(href)

// If prefetch has already been triggered, don't trigger it again.
if (
prefetched.has(href) ||
prefetched.has(hrefWithBasePath) ||
(typeof window !== 'undefined' && isBot(window.navigator.userAgent))
) {
return
}
prefetched.add(href)
const url = new URL(href, location.origin)
prefetched.add(hrefWithBasePath)
const url = new URL(hrefWithBasePath, location.origin)
// External urls can't be prefetched in the same way.
if (isExternalURL(url)) {
return
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/app-dir/app-basepath/app/another/page.js
@@ -0,0 +1,3 @@
export default function Page() {
return <div id="page-2">Page 2</div>
}
7 changes: 7 additions & 0 deletions test/e2e/app-dir/app-basepath/app/layout.js
@@ -0,0 +1,7 @@
export default function Root({ children }) {
return (
<html>
<body>{children}</body>
</html>
)
}
10 changes: 10 additions & 0 deletions test/e2e/app-dir/app-basepath/app/page.js
@@ -0,0 +1,10 @@
import Link from 'next/link'

export default function Page() {
return (
<div>
<h1>Test Page</h1>
<Link href="/another">Go to page 2</Link>
</div>
)
}
32 changes: 32 additions & 0 deletions test/e2e/app-dir/app-basepath/index.test.ts
@@ -0,0 +1,32 @@
import { createNextDescribe } from 'e2e-utils'

createNextDescribe(
'app dir basepath',
{
files: __dirname,
skipDeployment: true,
dependencies: {
swr: '2.0.0-rc.0',
react: 'latest',
'react-dom': 'latest',
sass: 'latest',
},
},
({ next }) => {
it('should support `basePath`', async () => {
const html = await next.render('/base')
expect(html).toContain('<h1>Test Page</h1>')
})

it('should support Link with basePath prefixed', async () => {
const browser = await next.browser('/base')
expect(
await browser
.elementByCss('a[href="/base/another"]')
.click()
.waitForElementByCss('#page-2')
.text()
).toBe(`Page 2`)
})
}
)
6 changes: 6 additions & 0 deletions test/e2e/app-dir/app-basepath/next.config.js
@@ -0,0 +1,6 @@
module.exports = {
basePath: '/base',
experimental: {
appDir: true,
},
}

0 comments on commit 1c5983f

Please sign in to comment.