From d34b921cab42e54f587ee66c77092022b3e7001b Mon Sep 17 00:00:00 2001 From: Slawek Kolodziej Date: Mon, 18 May 2020 14:10:59 +0200 Subject: [PATCH 1/3] Copy proper amp files for dynamic ssg pages --- packages/next/build/index.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 488b1caf5b455e..22e997c02acb34 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -827,7 +827,7 @@ export default async function build(dir: string, conf = null): Promise { await moveExportedPage(page, file, isSsg, 'html') } - if (hasAmp) { + if (hasAmp && (!isSsg || (isSsg && !isDynamic))) { await moveExportedPage(`${page}.amp`, `${file}.amp`, isSsg, 'html') } @@ -851,6 +851,16 @@ export default async function build(dir: string, conf = null): Promise { for (const route of extraRoutes) { await moveExportedPage(route, route, true, 'html') await moveExportedPage(route, route, true, 'json') + + if (hasAmp) { + await moveExportedPage( + `${route}.amp`, + `${route}.amp`, + true, + 'html' + ) + } + finalPrerenderRoutes[route] = { initialRevalidateSeconds: exportConfig.initialPageRevalidationMap[route], From 904a72182eef49ca5257174a0b1f521015163dde Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 18 May 2020 16:28:14 -0500 Subject: [PATCH 2/3] Add tests and correct serving hybrid AMP/SSG pages --- packages/next/build/index.ts | 7 +++++ packages/next/export/worker.js | 8 ++++++ .../next/next-server/server/next-server.ts | 7 +++-- .../amphtml-ssg/pages/blog/[slug].js | 27 +++++++++++++++++++ .../amphtml-ssg/test/index.test.js | 16 +++++++++++ 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 test/integration/amphtml-ssg/pages/blog/[slug].js diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index fa1b689eff4c74..ae214e42dd19cb 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -840,6 +840,7 @@ export default async function build(dir: string, conf = null): Promise { if (hasAmp && (!isSsg || (isSsg && !isDynamic))) { await moveExportedPage(`${page}.amp`, `${file}.amp`, isSsg, 'html') + await moveExportedPage(`${page}.amp`, `${file}.amp`, isSsg, 'json') } if (isSsg) { @@ -870,6 +871,12 @@ export default async function build(dir: string, conf = null): Promise { true, 'html' ) + await moveExportedPage( + `${route}.amp`, + `${route}.amp`, + true, + 'json' + ) } finalPrerenderRoutes[route] = { diff --git a/packages/next/export/worker.js b/packages/next/export/worker.js index ada50652170b44..34dd89efedde78 100644 --- a/packages/next/export/worker.js +++ b/packages/next/export/worker.js @@ -269,6 +269,14 @@ export default async function ({ JSON.stringify(curRenderOpts.pageData), 'utf8' ) + + if (curRenderOpts.hybridAmp) { + await promises.writeFile( + dataFile.replace(/\.json$/, '.amp.json'), + JSON.stringify(curRenderOpts.pageData), + 'utf8' + ) + } } results.fromBuildExportRevalidate = curRenderOpts.revalidate diff --git a/packages/next/next-server/server/next-server.ts b/packages/next/next-server/server/next-server.ts index 7ce91183e2ab4a..51b79a6f6dcba0 100644 --- a/packages/next/next-server/server/next-server.ts +++ b/packages/next/next-server/server/next-server.ts @@ -1025,9 +1025,7 @@ export default class Server { } // Compute the iSSG cache key - let urlPathname = `${parseUrl(req.url || '').pathname!}${ - query.amp ? '.amp' : '' - }` + let urlPathname = `${parseUrl(req.url || '').pathname!}` // remove /_next/data prefix from urlPathname so it matches // for direct page visit and /_next/data visit @@ -1039,10 +1037,11 @@ export default class Server { const ssgCacheKey = isPreviewMode ? undefined // Preview mode bypasses the cache - : urlPathname + : `${urlPathname}${query.amp ? '.amp' : ''}` // Complete the response with cached data if its present const cachedData = ssgCacheKey ? await getSprCache(ssgCacheKey) : undefined + if (cachedData) { const data = isDataReq ? JSON.stringify(cachedData.pageData) diff --git a/test/integration/amphtml-ssg/pages/blog/[slug].js b/test/integration/amphtml-ssg/pages/blog/[slug].js new file mode 100644 index 00000000000000..38f28cd7f387b1 --- /dev/null +++ b/test/integration/amphtml-ssg/pages/blog/[slug].js @@ -0,0 +1,27 @@ +import { useAmp } from 'next/amp' + +export const config = { + amp: 'hybrid', +} + +export const getStaticProps = () => { + return { + props: { + hello: 'hello', + random: Math.random(), + }, + } +} + +export const getStaticPaths = () => ({ + paths: ['/blog/post-1', '/blog/post-2'], + fallback: false, +}) + +export default ({ hello, random }) => ( + <> +

useAmp: {useAmp() ? 'yes' : 'no'}

+

{hello}

+

{random}

+ +) diff --git a/test/integration/amphtml-ssg/test/index.test.js b/test/integration/amphtml-ssg/test/index.test.js index 0e1f6c401083e2..8fae756665f500 100644 --- a/test/integration/amphtml-ssg/test/index.test.js +++ b/test/integration/amphtml-ssg/test/index.test.js @@ -46,6 +46,20 @@ const runTests = (isDev = false) => { expect($('#hello').text()).toContain('hello') }) + it('should load dynamic hybrid SSG/AMP page', async () => { + const html = await renderViaHTTP(appPort, '/blog/post-1') + const $ = cheerio.load(html) + expect($('#use-amp').text()).toContain('no') + expect($('#hello').text()).toContain('hello') + }) + + it('should load dynamic hybrid SSG/AMP page with query', async () => { + const html = await renderViaHTTP(appPort, '/blog/post-1?amp=1') + const $ = cheerio.load(html) + expect($('#use-amp').text()).toContain('yes') + expect($('#hello').text()).toContain('hello') + }) + it('should load a hybrid amp page with query correctly', async () => { const html = await renderViaHTTP(appPort, '/hybrid?amp=1') @@ -139,6 +153,8 @@ describe('AMP SSG Support', () => { expect(await fsExists(outFile('hybrid.html'))).toBe(true) expect(await fsExists(outFile('amp.amp.html'))).toBe(false) expect(await fsExists(outFile('hybrid.amp.html'))).toBe(true) + expect(await fsExists(outFile('blog/post-1.html'))).toBe(true) + expect(await fsExists(outFile('blog/post-1.amp.html'))).toBe(true) expect( await fsExists(outFile(join('_next/data', buildId, 'amp.json'))) From 32612faf049221489299708814703b4367d2df5a Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 18 May 2020 16:46:12 -0500 Subject: [PATCH 3/3] Add SSG check --- packages/next/build/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index ae214e42dd19cb..ef6e2302d8fc92 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -840,7 +840,10 @@ export default async function build(dir: string, conf = null): Promise { if (hasAmp && (!isSsg || (isSsg && !isDynamic))) { await moveExportedPage(`${page}.amp`, `${file}.amp`, isSsg, 'html') - await moveExportedPage(`${page}.amp`, `${file}.amp`, isSsg, 'json') + + if (isSsg) { + await moveExportedPage(`${page}.amp`, `${file}.amp`, isSsg, 'json') + } } if (isSsg) {