Skip to content

Commit

Permalink
Fix asPath handling for data route revalidation in minimal mode (#36660)
Browse files Browse the repository at this point in the history
  • Loading branch information
ijjk committed May 3, 2022
1 parent fdc4ab8 commit 95fb221
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 19 deletions.
41 changes: 22 additions & 19 deletions packages/next/server/base-server.ts
Expand Up @@ -465,8 +465,10 @@ export default abstract class Server<ServerOptions extends Options = Options> {
: matchedPathname

let srcPathname = isDataUrl
? parsedMatchedPath.pathname?.replace(/\.json$/, '') ||
matchedPathnameNoExt
? this.stripNextDataPath(
parsedMatchedPath.pathname?.replace(/\.json$/, '') ||
matchedPathnameNoExt
) || '/'
: matchedPathnameNoExt

if (this.nextConfig.i18n) {
Expand Down Expand Up @@ -1338,21 +1340,6 @@ export default abstract class Server<ServerOptions extends Options = Options> {
this.nextConfig.i18n?.locales
).pathname

const stripNextDataPath = (path: string) => {
if (path.includes(this.buildId)) {
const splitPath = path.substring(
path.indexOf(this.buildId) + this.buildId.length
)

path = denormalizePagePath(splitPath.replace(/\.json$/, ''))
}

if (this.nextConfig.i18n) {
return normalizeLocalePath(path, locales).pathname
}
return path
}

const handleRedirect = (pageData: any) => {
const redirect = {
destination: pageData.pageProps.__N_REDIRECT,
Expand Down Expand Up @@ -1383,8 +1370,8 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// remove /_next/data prefix from urlPathname so it matches
// for direct page visit and /_next/data visit
if (isDataReq) {
resolvedUrlPathname = stripNextDataPath(resolvedUrlPathname)
urlPathname = stripNextDataPath(urlPathname)
resolvedUrlPathname = this.stripNextDataPath(resolvedUrlPathname)
urlPathname = this.stripNextDataPath(urlPathname)
}

let ssgCacheKey =
Expand Down Expand Up @@ -1743,6 +1730,22 @@ export default abstract class Server<ServerOptions extends Options = Options> {
}
}

private stripNextDataPath(path: string) {
if (path.includes(this.buildId)) {
const splitPath = path.substring(
path.indexOf(this.buildId) + this.buildId.length
)

path = denormalizePagePath(splitPath.replace(/\.json$/, ''))
}

if (this.nextConfig.i18n) {
const { locales } = this.nextConfig.i18n
return normalizeLocalePath(path, locales).pathname
}
return path
}

private async renderToResponse(
ctx: RequestContext
): Promise<ResponsePayload | null> {
Expand Down
33 changes: 33 additions & 0 deletions test/production/required-server-files.test.ts
Expand Up @@ -56,6 +56,10 @@ describe('should set-up next', () => {
source: '/an-ssg-path',
destination: '/hello.txt',
},
{
source: '/fallback-false/:path',
destination: '/hello.txt',
},
],
afterFiles: [
{
Expand Down Expand Up @@ -980,6 +984,35 @@ describe('should set-up next', () => {
expect(JSON.parse($('#router').text()).asPath).toBe('/an-ssg-path')
})

it('should have correct asPath on dynamic SSG page fallback correctly', async () => {
const toCheck = [
{
pathname: '/fallback-false/first',
matchedPath: '/fallback-false/first',
},
{
pathname: '/fallback-false/first',
matchedPath: `/_next/data/${next.buildId}/fallback-false/first.json`,
},
]
for (const check of toCheck) {
console.warn('checking', check)
const res = await fetchViaHTTP(appPort, check.pathname, undefined, {
headers: {
'x-matched-path': check.matchedPath,
},
redirect: 'manual',
})

const html = await res.text()
const $ = cheerio.load(html)
expect($('#page').text()).toBe('blog slug')
expect($('#asPath').text()).toBe('/fallback-false/first')
expect($('#pathname').text()).toBe('/fallback-false/[slug]')
expect(JSON.parse($('#query').text())).toEqual({ slug: 'first' })
}
})

it('should copy and read .env file', async () => {
const res = await fetchViaHTTP(appPort, '/api/env')

Expand Down
@@ -0,0 +1,35 @@
import { useRouter } from 'next/router'

export default function Page(props) {
const router = useRouter()

return (
<>
<p id="page">blog slug</p>
<p id="props">{JSON.stringify(props)}</p>
<p id="query">{JSON.stringify(router.query)}</p>
<p id="pathname">{router.pathname}</p>
<p id="asPath">{router.asPath}</p>
</>
)
}

export function getStaticProps({ params }) {
console.log({ blogSlug: true, params })

return {
props: {
random: Math.random() + Date.now(),
blogSlug: true,
params,
},
revalidate: 1,
}
}

export function getStaticPaths() {
return {
paths: ['/fallback-false/first', '/fallback-false/second'],
fallback: false,
}
}

0 comments on commit 95fb221

Please sign in to comment.