Fix basepath root handling (#14756)

Fixes https://github.com/vercel/next.js/issues/14734
This commit is contained in:
Jan Potoms 2020-07-02 05:48:10 +02:00 committed by GitHub
parent 9e83ba8cf6
commit 066a18ffc8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 10 deletions

View file

@ -23,19 +23,15 @@ import {
const basePath = (process.env.__NEXT_ROUTER_BASEPATH as string) || ''
export function addBasePath(path: string): string {
return `${basePath}${path}`
return basePath ? (path === '/' ? basePath : basePath + path) : path
}
export function delBasePath(path: string): string {
return path.substr(basePath.length)
}
function toRoute(path: string): string {
return path.replace(/\/$/, '') || '/'
return path.slice(basePath.length) || '/'
}
function prepareRoute(path: string) {
return toRoute(delBasePath(path || '') || '/')
return removePathTrailingSlash(delBasePath(path || '/'))
}
type Url = UrlObject | string
@ -196,7 +192,7 @@ export default class Router implements BaseRouter {
}
) {
// represents the current component key
this.route = toRoute(pathname)
this.route = removePathTrailingSlash(pathname)
// set up the component cache (by route keys)
this.components = {}
@ -443,7 +439,7 @@ export default class Router implements BaseRouter {
method = 'replaceState'
}
const route = toRoute(pathname)
const route = removePathTrailingSlash(pathname)
const { shallow = false } = options
const cleanedAs = delBasePath(as)
@ -782,7 +778,7 @@ export default class Router implements BaseRouter {
if (process.env.NODE_ENV !== 'production') {
return
}
const route = toRoute(pathname)
const route = removePathTrailingSlash(pathname)
Promise.all([
this.pageLoader.prefetchData(url, asPath),
this.pageLoader[options.priority ? 'loadPage' : 'prefetch'](route),

View file

@ -0,0 +1,11 @@
import Link from 'next/link'
export default function Page() {
return (
<>
<Link href="/">
<a id="link-back">back</a>
</Link>
</>
)
}

View file

@ -312,6 +312,13 @@ const runTests = (context, dev = false) => {
expect(pathname).toBe('/docs/other-page')
})
it('should have correct href for a link to /', async () => {
const browser = await webdriver(context.appPort, '/docs/link-to-root')
const href = await browser.elementByCss('#link-back').getAttribute('href')
const { pathname } = url.parse(href)
expect(pathname).toBe('/docs')
})
it('should show 404 for page not under the /docs prefix', async () => {
const text = await renderViaHTTP(context.appPort, '/hello')
expect(text).not.toContain('Hello World')