Fix asPath of rewrite without basePath (#15760)

Fixes https://github.com/vercel/next.js/issues/15755
This commit is contained in:
Jan Potoms 2020-08-01 13:51:47 +02:00 committed by GitHub
parent 6366727550
commit 1b033423dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 12 deletions

View file

@ -9,7 +9,7 @@ import { RouterContext } from '../next-server/lib/router-context'
import { isDynamicRoute } from '../next-server/lib/router/utils/is-dynamic'
import * as envConfig from '../next-server/lib/runtime-config'
import { getURL, loadGetInitialProps, ST } from '../next-server/lib/utils'
import { delBasePath } from '../next-server/lib/router/router'
import { hasBasePath, delBasePath } from '../next-server/lib/router/router'
import initHeadManager from './head-manager'
import PageLoader from './page-loader'
import measureWebVitals from './performance-relayer'
@ -52,15 +52,7 @@ envConfig.setConfig({
let asPath = getURL()
// make sure not to attempt stripping basePath for 404s
if (
page !== '/404' &&
!(
page === '/_error' &&
hydrateProps &&
hydrateProps.pageProps &&
hydrateProps.pageProps.statusCode === 404
)
) {
if (hasBasePath(asPath)) {
asPath = delBasePath(asPath)
}

View file

@ -30,6 +30,10 @@ function buildCancellationError() {
})
}
export function hasBasePath(path: string): boolean {
return path === basePath || path.startsWith(basePath + '/')
}
export function addBasePath(path: string): string {
return basePath
? path === '/'
@ -269,7 +273,6 @@ export default class Router implements BaseRouter {
if (as.substr(0, 2) !== '//') {
// in order for `e.state` to work on the `onpopstate` event
// we have to register the initial route upon initialization
this.changeState(
'replaceState',
formatWithValidation({ pathname: addBasePath(pathname), query }),
@ -450,7 +453,7 @@ export default class Router implements BaseRouter {
this.abortComponentLoad(this._inFlightRoute)
}
const cleanedAs = delBasePath(as)
const cleanedAs = hasBasePath(as) ? delBasePath(as) : as
this._inFlightRoute = as
// If the url change is only related to a hash change

View file

@ -141,6 +141,38 @@ const runTests = (context, dev = false) => {
expect(html).toContain('getServerSideProps')
})
it('should have correct asPath for rewrite without basePath', async () => {
const browser = await webdriver(context.appPort, '/rewrite-no-basePath')
expect(await browser.eval(() => window.location.pathname)).toBe(
'/rewrite-no-basePath'
)
expect(await browser.eval(() => window.next.router.asPath)).toBe(
'/rewrite-no-basePath'
)
expect(await browser.eval(() => window.next.router.pathname)).toBe('/gssp')
})
it('should have correct asPath for rewrite without basePath on back()', async () => {
const browser = await webdriver(context.appPort, '/rewrite-no-basePath')
await browser.eval(() => (window.navigationMarker = true))
await browser.eval(() => window.next.router.push('/hello'))
await check(
() => browser.eval(() => window.location.pathname),
'/docs/hello'
)
await browser.back()
await check(
() => browser.eval(() => window.location.pathname),
'/rewrite-no-basePath'
)
await check(
() => browser.eval(() => window.next.router.asPath),
'/rewrite-no-basePath'
)
expect(await browser.eval(() => window.next.router.pathname)).toBe('/gssp')
expect(await browser.eval(() => window.navigationMarker)).toBe(true)
})
it('should redirect with basePath by default', async () => {
const res = await fetchViaHTTP(
context.appPort,
@ -216,6 +248,27 @@ const runTests = (context, dev = false) => {
expect(pathname).toBe('/missing')
})
it('should handle 404 urls that start with basePath', async () => {
const browser = await webdriver(context.appPort, '/docshello')
expect(await browser.eval(() => window.next.router.asPath)).toBe(
'/docshello'
)
expect(await browser.eval(() => window.location.pathname)).toBe(
'/docshello'
)
})
it('should navigating back to a non-basepath 404 that starts with basepath', async () => {
const browser = await webdriver(context.appPort, '/docshello')
await browser.eval(() => window.next.router.push('/hello'))
await browser.waitForElementByCss('#pathname')
await browser.back()
check(() => browser.eval(() => window.location.pathname), '/docshello')
expect(await browser.eval(() => window.next.router.asPath)).toBe(
'/docshello'
)
})
it('should update dynamic params after mount correctly', async () => {
const browser = await webdriver(context.appPort, '/docs/hello-dynamic')
const text = await browser.elementByCss('#slug').text()