diff --git a/packages/next/next-server/lib/router/router.ts b/packages/next/next-server/lib/router/router.ts index cc140d267cad2..c694ff2450446 100644 --- a/packages/next/next-server/lib/router/router.ts +++ b/packages/next/next-server/lib/router/router.ts @@ -30,8 +30,10 @@ function toRoute(path: string): string { return path.replace(/\/$/, '') || '/' } -const prepareRoute = (path: string) => - toRoute(!path || path === '/' ? '/index' : path) +function prepareRoute(path: string) { + path = delBasePath(path || '') + return toRoute(!path || path === '/' ? '/index' : path) +} type Url = UrlObject | string @@ -106,7 +108,7 @@ function fetchNextData( formatWithValidation({ pathname: addBasePath( // @ts-ignore __NEXT_DATA__ - `/_next/data/${__NEXT_DATA__.buildId}${delBasePath(pathname)}.json` + `/_next/data/${__NEXT_DATA__.buildId}${pathname}.json` ), query, }), @@ -446,13 +448,12 @@ export default class Router implements BaseRouter { const route = toRoute(pathname) const { shallow = false } = options + const cleanedAs = delBasePath(as) if (isDynamicRoute(route)) { - const { pathname: asPathname } = parse(as) + const { pathname: asPathname } = parse(cleanedAs) const routeRegex = getRouteRegex(route) - const routeMatch = getRouteMatcher(routeRegex)( - delBasePath(asPathname || '') - ) + const routeMatch = getRouteMatcher(routeRegex)(asPathname) if (!routeMatch) { const missingParams = Object.keys(routeRegex.groups).filter( (param) => !query[param] @@ -502,17 +503,15 @@ export default class Router implements BaseRouter { !(routeInfo.Component as any).getInitialProps } - this.set(route, pathname!, query, delBasePath(as), routeInfo).then( - () => { - if (error) { - Router.events.emit('routeChangeError', error, as) - throw error - } - - Router.events.emit('routeChangeComplete', as) - return resolve(true) + this.set(route, pathname!, query, cleanedAs, routeInfo).then(() => { + if (error) { + Router.events.emit('routeChangeError', error, as) + throw error } - ) + + Router.events.emit('routeChangeComplete', as) + return resolve(true) + }) }, reject ) diff --git a/test/integration/basepath/pages/hello.js b/test/integration/basepath/pages/hello.js index 4b6e07f5f6233..2df0ba7850588 100644 --- a/test/integration/basepath/pages/hello.js +++ b/test/integration/basepath/pages/hello.js @@ -32,6 +32,12 @@ export default () => (

catchall page

+
+ + +

index getStaticProps

+
+
{useRouter().basePath}
{useRouter().pathname}
diff --git a/test/integration/basepath/pages/index.js b/test/integration/basepath/pages/index.js new file mode 100644 index 0000000000000..c479bede452ce --- /dev/null +++ b/test/integration/basepath/pages/index.js @@ -0,0 +1,20 @@ +import { useRouter } from 'next/router' + +export const getStaticProps = () => { + return { + props: { + hello: 'hello', + }, + } +} + +export default function Index({ hello }) { + const { query, pathname } = useRouter() + return ( + <> +

{hello} world

+

{JSON.stringify(query)}

+

{pathname}

+ + ) +} diff --git a/test/integration/basepath/test/index.test.js b/test/integration/basepath/test/index.test.js index df39da42d2dbc..d3c889144c068 100644 --- a/test/integration/basepath/test/index.test.js +++ b/test/integration/basepath/test/index.test.js @@ -93,6 +93,41 @@ const runTests = (context, dev = false) => { }) } + it('should navigate to index page with getStaticProps', async () => { + const browser = await webdriver(context.appPort, '/docs/hello') + await browser.eval('window.beforeNavigate = "hi"') + + await browser.elementByCss('#index-gsp').click() + await browser.waitForElementByCss('#prop') + + expect(await browser.eval('window.beforeNavigate')).toBe('hi') + + expect(await browser.elementByCss('#prop').text()).toBe('hello world') + + expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({}) + + expect(await browser.elementByCss('#pathname').text()).toBe('/') + + if (!dev) { + const prefetches = await browser.elementsByCss('link[rel="prefetch"]') + let found = false + + for (const prefetch of prefetches) { + const fullHref = await prefetch.getAttribute('href') + const href = url.parse(fullHref).pathname + + if ( + href.startsWith('/docs/_next/data') && + href.endsWith('index.json') + ) { + found = true + } + } + + expect(found).toBe(true) + } + }) + it('should work with nested folder with same name as basePath', async () => { const html = await renderViaHTTP(context.appPort, '/docs/docs/another') expect(html).toContain('hello from another')