From e252554daf92755660b82fd8e45936a052621b82 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 14 Sep 2020 14:31:15 -0500 Subject: [PATCH 1/2] Fix API page check --- packages/next/build/index.ts | 4 +- .../prerender/pages/api-docs/[...slug].js | 27 +++++++++ test/integration/prerender/test/index.test.js | 59 +++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 test/integration/prerender/pages/api-docs/[...slug].js diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 93ca9cf52f9d3..60d8b35d03399 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -523,7 +523,9 @@ export default async function build( let isHybridAmp = false let ssgPageRoutes: string[] | null = null - const nonReservedPage = !page.match(/^\/(_app|_error|_document|api)/) + const nonReservedPage = !page.match( + /^\/(_app|_error|_document|api(\/|$))/ + ) if (nonReservedPage) { const serverBundle = getPagePath(page, distDir, isLikeServerless) diff --git a/test/integration/prerender/pages/api-docs/[...slug].js b/test/integration/prerender/pages/api-docs/[...slug].js new file mode 100644 index 0000000000000..e5483a0d6fa4d --- /dev/null +++ b/test/integration/prerender/pages/api-docs/[...slug].js @@ -0,0 +1,27 @@ +import { useRouter } from 'next/router' + +export const getStaticProps = () => { + return { + props: { + hello: 'world', + }, + } +} + +export const getStaticPaths = () => { + return { + paths: ['/api-docs/first'], + fallback: true, + } +} + +export default function Slug(props) { + if (useRouter().isFallback) return 'Loading...' + + return ( + <> +

API Docs

+

{JSON.stringify(props)}

+ + ) +} diff --git a/test/integration/prerender/test/index.test.js b/test/integration/prerender/test/index.test.js index 4f6cb7bc515cc..7d342156a33a3 100644 --- a/test/integration/prerender/test/index.test.js +++ b/test/integration/prerender/test/index.test.js @@ -142,6 +142,11 @@ const expectedManifestRoutes = () => ({ initialRevalidateSeconds: 1, srcRoute: null, }, + '/api-docs/first': { + dataRoute: `/_next/data/${buildId}/api-docs/first.json`, + initialRevalidateSeconds: false, + srcRoute: '/api-docs/[...slug]', + }, '/blocking-fallback-some/a': { dataRoute: `/_next/data/${buildId}/blocking-fallback-some/a.json`, initialRevalidateSeconds: 1, @@ -602,6 +607,38 @@ const runTests = (dev = false, isEmulatedServerless = false) => { }) } + it('should server prerendered path correctly for SSG pages that starts with api-docs', async () => { + const html = await renderViaHTTP(appPort, '/api-docs/first') + const $ = cheerio.load(html) + + expect($('#api-docs').text()).toBe('API Docs') + expect(JSON.parse($('#props').text())).toEqual({ + hello: 'world', + }) + }) + + it('should render correctly for SSG pages that starts with api-docs', async () => { + const browser = await webdriver(appPort, '/api-docs/second') + await browser.waitForElementByCss('#api-docs') + + expect(await browser.elementByCss('#api-docs').text()).toBe('API Docs') + expect(JSON.parse(await browser.elementByCss('#props').text())).toEqual({ + hello: 'world', + }) + }) + + it('should return data correctly for SSG pages that starts with api-docs', async () => { + const data = await renderViaHTTP( + appPort, + `/_next/data/${buildId}/api-docs/first.json` + ) + const { pageProps } = JSON.parse(data) + + expect(pageProps).toEqual({ + hello: 'world', + }) + }) + it('should SSR catch-all page with brackets in param as string', async () => { const html = await renderViaHTTP( appPort, @@ -1136,6 +1173,20 @@ const runTests = (dev = false, isEmulatedServerless = false) => { ), page: '/another', }, + { + dataRouteRegex: normalizeRegEx( + `^\\/_next\\/data\\/${escapeRegex( + buildId + )}\\/api\\-docs\\/(.+?)\\.json$` + ), + namedDataRouteRegex: `^/_next/data/${escapeRegex( + buildId + )}/api\\-docs/(?.+?)\\.json$`, + page: '/api-docs/[...slug]', + routeKeys: { + slug: 'slug', + }, + }, { dataRouteRegex: normalizeRegEx( `^\\/_next\\/data\\/${escapeRegex(buildId)}\\/bad-gssp.json$` @@ -1388,6 +1439,14 @@ const runTests = (dev = false, isEmulatedServerless = false) => { expect(manifest.version).toBe(2) expect(manifest.routes).toEqual(expectedManifestRoutes()) expect(manifest.dynamicRoutes).toEqual({ + '/api-docs/[...slug]': { + dataRoute: `/_next/data/${buildId}/api-docs/[...slug].json`, + dataRouteRegex: normalizeRegEx( + `^\\/_next\\/data\\/${escapedBuildId}\\/api\\-docs\\/(.+?)\\.json$` + ), + fallback: '/api-docs/[...slug].html', + routeRegex: normalizeRegEx(`^\\/api\\-docs\\/(.+?)(?:\\/)?$`), + }, '/blocking-fallback-once/[slug]': { dataRoute: `/_next/data/${buildId}/blocking-fallback-once/[slug].json`, dataRouteRegex: normalizeRegEx( From 86abc8f86e7df3243c8f0eaca6ce9ece0923a3e5 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 14 Sep 2020 16:16:50 -0500 Subject: [PATCH 2/2] Update test --- test/integration/prerender/test/index.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/prerender/test/index.test.js b/test/integration/prerender/test/index.test.js index 7d342156a33a3..823c905a3b070 100644 --- a/test/integration/prerender/test/index.test.js +++ b/test/integration/prerender/test/index.test.js @@ -2054,6 +2054,7 @@ describe('SSG Prerender', () => { '/non-json/[p].js', '/blog/[post]/index.js', '/fallback-only/[slug].js', + '/api-docs/[...slug].js', ] const fallbackBlockingPages = [ '/blocking-fallback/[slug].js',