From c8f645c509b4394cbe06108d250803f5dd8f62f4 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Mon, 14 Feb 2022 12:18:05 +0000 Subject: [PATCH 1/6] fix: prepend basePath to static file URLs --- demos/static-root/next.config.js | 2 +- src/helpers/files.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/demos/static-root/next.config.js b/demos/static-root/next.config.js index 59274ee24d..22e35d86d1 100644 --- a/demos/static-root/next.config.js +++ b/demos/static-root/next.config.js @@ -21,7 +21,7 @@ module.exports = { }, trailingSlash: true, // Configurable site features _to_ support: - // basePath: '/docs', + basePath: '/docs', // Rewrites allow you to map an incoming request path to a different destination path. async rewrites() { return { diff --git a/src/helpers/files.ts b/src/helpers/files.ts index 757f5abca1..7dcff53738 100644 --- a/src/helpers/files.ts +++ b/src/helpers/files.ts @@ -73,10 +73,12 @@ export const moveStaticPages = async ({ netlifyConfig, target, i18n, + basePath, }: { netlifyConfig: NetlifyConfig target: 'server' | 'serverless' | 'experimental-serverless-trace' i18n: NextConfig['i18n'] + basePath?: string }): Promise => { console.log('Moving static page files to serve from CDN...') const outputDir = join(netlifyConfig.build.publish, target === 'server' ? 'server' : 'serverless') @@ -117,11 +119,12 @@ export const moveStaticPages = async ({ const isData = file.endsWith('.json') const source = join(root, file) const targetFile = isData ? join(dataDir, file) : file + const targetPath = basePath ? join(basePath, targetFile) : targetFile files.push(file) - filesManifest[file] = targetFile + filesManifest[file] = targetPath - const dest = join(netlifyConfig.build.publish, targetFile) + const dest = join(netlifyConfig.build.publish, targetPath) try { await move(source, dest) From 5d28a4d8aa2cb57b677ac84ad23d8a28806de8e6 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Mon, 14 Feb 2022 12:38:54 +0000 Subject: [PATCH 2/6] chore: add basePath demo --- demos/base-path/.eslintrc | 4 + demos/base-path/.gitignore | 34 +++++ demos/base-path/README.md | 34 +++++ demos/base-path/local-plugin/index.js | 1 + demos/base-path/local-plugin/manifest.yml | 1 + .../base-path/local-plugin/package-lock.json | 5 + demos/base-path/local-plugin/package.json | 11 ++ demos/base-path/netlify.toml | 21 +++ demos/base-path/next.config.js | 46 +++++++ demos/base-path/pages/_app.js | 7 + demos/base-path/pages/another.js | 22 ++++ demos/base-path/pages/api/hello.js | 5 + .../pages/dynamic/[dynamic]/index.js | 13 ++ .../pages/fallback/[dynamic]/index.js | 13 ++ demos/base-path/pages/index.js | 37 ++++++ demos/base-path/public/favicon.ico | Bin 0 -> 15086 bytes demos/base-path/styles/Home.module.css | 121 ++++++++++++++++++ demos/base-path/styles/globals.css | 16 +++ demos/static-root/next.config.js | 2 +- 19 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 demos/base-path/.eslintrc create mode 100644 demos/base-path/.gitignore create mode 100644 demos/base-path/README.md create mode 100644 demos/base-path/local-plugin/index.js create mode 100644 demos/base-path/local-plugin/manifest.yml create mode 100644 demos/base-path/local-plugin/package-lock.json create mode 100644 demos/base-path/local-plugin/package.json create mode 100644 demos/base-path/netlify.toml create mode 100644 demos/base-path/next.config.js create mode 100644 demos/base-path/pages/_app.js create mode 100644 demos/base-path/pages/another.js create mode 100644 demos/base-path/pages/api/hello.js create mode 100644 demos/base-path/pages/dynamic/[dynamic]/index.js create mode 100644 demos/base-path/pages/fallback/[dynamic]/index.js create mode 100644 demos/base-path/pages/index.js create mode 100644 demos/base-path/public/favicon.ico create mode 100644 demos/base-path/styles/Home.module.css create mode 100644 demos/base-path/styles/globals.css diff --git a/demos/base-path/.eslintrc b/demos/base-path/.eslintrc new file mode 100644 index 0000000000..abd5579b49 --- /dev/null +++ b/demos/base-path/.eslintrc @@ -0,0 +1,4 @@ +{ + "extends": "next", + "root": true +} diff --git a/demos/base-path/.gitignore b/demos/base-path/.gitignore new file mode 100644 index 0000000000..1437c53f70 --- /dev/null +++ b/demos/base-path/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel diff --git a/demos/base-path/README.md b/demos/base-path/README.md new file mode 100644 index 0000000000..b12f3e33e7 --- /dev/null +++ b/demos/base-path/README.md @@ -0,0 +1,34 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. + +[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. + +The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/demos/base-path/local-plugin/index.js b/demos/base-path/local-plugin/index.js new file mode 100644 index 0000000000..9e852e382e --- /dev/null +++ b/demos/base-path/local-plugin/index.js @@ -0,0 +1 @@ +module.exports = require('../../../lib') diff --git a/demos/base-path/local-plugin/manifest.yml b/demos/base-path/local-plugin/manifest.yml new file mode 100644 index 0000000000..7091f91411 --- /dev/null +++ b/demos/base-path/local-plugin/manifest.yml @@ -0,0 +1 @@ +name: '@netlify/plugin-nextjs-local' diff --git a/demos/base-path/local-plugin/package-lock.json b/demos/base-path/local-plugin/package-lock.json new file mode 100644 index 0000000000..11a2e6611e --- /dev/null +++ b/demos/base-path/local-plugin/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "local-plugin", + "version": "1.0.0", + "lockfileVersion": 1 +} diff --git a/demos/base-path/local-plugin/package.json b/demos/base-path/local-plugin/package.json new file mode 100644 index 0000000000..d692119a5b --- /dev/null +++ b/demos/base-path/local-plugin/package.json @@ -0,0 +1,11 @@ +{ + "name": "local-plugin", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "preinstall": "cd ../../.. && npm i" + }, + "author": "", + "license": "ISC" +} diff --git a/demos/base-path/netlify.toml b/demos/base-path/netlify.toml new file mode 100644 index 0000000000..288149fe89 --- /dev/null +++ b/demos/base-path/netlify.toml @@ -0,0 +1,21 @@ +[build] +command = "next build" +publish = ".next" +ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF ../../" + +[build.environment] +# cache Cypress binary in local "node_modules" folder +# so Netlify caches it +CYPRESS_CACHE_FOLDER = "../node_modules/.CypressBinary" + +[dev] +framework = "#static" + +[[plugins]] +package = "./local-plugin" + +[[plugins]] +package = "@netlify/plugin-local-install-core" + +[[context.deploy-preview.plugins]] +package = "netlify-plugin-cypress" \ No newline at end of file diff --git a/demos/base-path/next.config.js b/demos/base-path/next.config.js new file mode 100644 index 0000000000..22e35d86d1 --- /dev/null +++ b/demos/base-path/next.config.js @@ -0,0 +1,46 @@ +module.exports = { + // Configurable site features we support: + // distDir: 'build', + generateBuildId: () => 'build-id', + i18n: { + defaultLocale: 'en', + locales: ['en', 'es', 'fr'], + }, + async headers() { + return [ + { + source: '/', + headers: [ + { + key: 'x-custom-header', + value: 'my custom header value', + }, + ], + }, + ] + }, + trailingSlash: true, + // Configurable site features _to_ support: + basePath: '/docs', + // Rewrites allow you to map an incoming request path to a different destination path. + async rewrites() { + return { + beforeFiles: [ + { + source: '/old/:path*', + destination: '/:path*', + }, + ], + } + }, + // Redirects allow you to redirect an incoming request path to a different destination path. + async redirects() { + return [ + { + source: '/redirectme', + destination: '/', + permanent: true, + }, + ] + }, +} diff --git a/demos/base-path/pages/_app.js b/demos/base-path/pages/_app.js new file mode 100644 index 0000000000..1e1cec9242 --- /dev/null +++ b/demos/base-path/pages/_app.js @@ -0,0 +1,7 @@ +import '../styles/globals.css' + +function MyApp({ Component, pageProps }) { + return +} + +export default MyApp diff --git a/demos/base-path/pages/another.js b/demos/base-path/pages/another.js new file mode 100644 index 0000000000..e9cebb8bfd --- /dev/null +++ b/demos/base-path/pages/another.js @@ -0,0 +1,22 @@ +import Head from 'next/head' +import { useRouter } from 'next/router' +import styles from '../styles/Home.module.css' + +export default function Home() { + const { locale } = useRouter() + return ( +
+ + Create Next App + + + + +
+

Another page

+
+ + +
+ ) +} diff --git a/demos/base-path/pages/api/hello.js b/demos/base-path/pages/api/hello.js new file mode 100644 index 0000000000..9987aff4c3 --- /dev/null +++ b/demos/base-path/pages/api/hello.js @@ -0,0 +1,5 @@ +// Next.js API route support: https://nextjs.org/docs/api-routes/introduction + +export default (req, res) => { + res.status(200).json({ name: 'John Doe' }) +} diff --git a/demos/base-path/pages/dynamic/[dynamic]/index.js b/demos/base-path/pages/dynamic/[dynamic]/index.js new file mode 100644 index 0000000000..6bc47a52e2 --- /dev/null +++ b/demos/base-path/pages/dynamic/[dynamic]/index.js @@ -0,0 +1,13 @@ +function Dynamic() { + return
This is the page with a dynamic path.
+} + +export const getStaticPaths = async () => { + return { paths: ['/dynamic/dynamic-1'], fallback: false } +} + +export const getStaticProps = ({ params }) => { + return { props: params } +} + +export default Dynamic diff --git a/demos/base-path/pages/fallback/[dynamic]/index.js b/demos/base-path/pages/fallback/[dynamic]/index.js new file mode 100644 index 0000000000..d89a0d6e70 --- /dev/null +++ b/demos/base-path/pages/fallback/[dynamic]/index.js @@ -0,0 +1,13 @@ +function Dynamic() { + return
This is the page with a dynamic path.
+} + +export const getStaticPaths = async () => { + return { paths: ['/fallback/dynamic-1'], fallback: 'blocking' } +} + +export const getStaticProps = ({ params }) => { + return { props: params } +} + +export default Dynamic diff --git a/demos/base-path/pages/index.js b/demos/base-path/pages/index.js new file mode 100644 index 0000000000..e9432c9c49 --- /dev/null +++ b/demos/base-path/pages/index.js @@ -0,0 +1,37 @@ +import Head from 'next/head' +import Link from 'next/link' +import { useRouter } from 'next/router' +import styles from '../styles/Home.module.css' + +export default function Home() { + const { locale } = useRouter() + return ( +
+ + Create Next App + + + + +
+

+ Welcome to Next.js! +

+ +

The current locale is {locale}

+ +
+ +

Dynamic Page

+ + +

Fallback Page

+ + +

Redirect me

+ +
+
+
+ ) +} diff --git a/demos/base-path/public/favicon.ico b/demos/base-path/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4965832f2c9b0605eaa189b7c7fb11124d24e48a GIT binary patch literal 15086 zcmeHOOH5Q(7(R0cc?bh2AT>N@1PWL!LLfZKyG5c!MTHoP7_p!sBz0k$?pjS;^lmgJ zU6^i~bWuZYHL)9$wuvEKm~qo~(5=Lvx5&Hv;?X#m}i|`yaGY4gX+&b>tew;gcnRQA1kp zBbm04SRuuE{Hn+&1wk%&g;?wja_Is#1gKoFlI7f`Gt}X*-nsMO30b_J@)EFNhzd1QM zdH&qFb9PVqQOx@clvc#KAu}^GrN`q5oP(8>m4UOcp`k&xwzkTio*p?kI4BPtIwX%B zJN69cGsm=x90<;Wmh-bs>43F}ro$}Of@8)4KHndLiR$nW?*{Rl72JPUqRr3ta6e#A z%DTEbi9N}+xPtd1juj8;(CJt3r9NOgb>KTuK|z7!JB_KsFW3(pBN4oh&M&}Nb$Ee2 z$-arA6a)CdsPj`M#1DS>fqj#KF%0q?w50GN4YbmMZIoF{e1yTR=4ablqXHBB2!`wM z1M1ke9+<);|AI;f=2^F1;G6Wfpql?1d5D4rMr?#f(=hkoH)U`6Gb)#xDLjoKjp)1;Js@2Iy5yk zMXUqj+gyk1i0yLjWS|3sM2-1ECc;MAz<4t0P53%7se$$+5Ex`L5TQO_MMXXi04UDIU+3*7Ez&X|mj9cFYBXqM{M;mw_ zpw>azP*qjMyNSD4hh)XZt$gqf8f?eRSFX8VQ4Y+H3jAtvyTrXr`qHAD6`m;aYmH2zOhJC~_*AuT} zvUxC38|JYN94i(05R)dVKgUQF$}#cxV7xZ4FULqFCNX*Forhgp*yr6;DsIk=ub0Hv zpk2L{9Q&|uI^b<6@i(Y+iSxeO_n**4nRLc`P!3ld5jL=nZRw6;DEJ*1z6Pvg+eW|$lnnjO zjd|8>6l{i~UxI244CGn2kK@cJ|#ecwgSyt&HKA2)z zrOO{op^o*- Date: Mon, 14 Feb 2022 12:57:24 +0000 Subject: [PATCH 3/6] chore: log event --- src/templates/getHandler.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/templates/getHandler.ts b/src/templates/getHandler.ts index be2d922858..7d3f20b75d 100644 --- a/src/templates/getHandler.ts +++ b/src/templates/getHandler.ts @@ -85,6 +85,8 @@ const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[str } return async function handler(event: HandlerEvent, context: HandlerContext) { + console.log(event) + let requestMode = mode // Ensure that paths are encoded - but don't double-encode them event.path = new URL(event.rawUrl).pathname From dfca883fa5c81bfd83c545fee22b37b097d1eeee Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Mon, 14 Feb 2022 13:06:30 +0000 Subject: [PATCH 4/6] fix: pass basePath --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 680f3e8583..fede662fb3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -85,7 +85,7 @@ const plugin: NetlifyPlugin = { } if (!process.env.SERVE_STATIC_FILES_FROM_ORIGIN) { - await moveStaticPages({ target, netlifyConfig, i18n }) + await moveStaticPages({ target, netlifyConfig, i18n, basePath }) } await generateStaticRedirects({ From c8c7b79433d475cf6b2d352a7b81929bbccdb04a Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Mon, 14 Feb 2022 13:08:03 +0000 Subject: [PATCH 5/6] chore: remove cypress from basepath demo for now --- demos/static-root/netlify.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demos/static-root/netlify.toml b/demos/static-root/netlify.toml index 288149fe89..ce3073f46f 100644 --- a/demos/static-root/netlify.toml +++ b/demos/static-root/netlify.toml @@ -17,5 +17,5 @@ package = "./local-plugin" [[plugins]] package = "@netlify/plugin-local-install-core" -[[context.deploy-preview.plugins]] -package = "netlify-plugin-cypress" \ No newline at end of file +# [[context.deploy-preview.plugins]] +# package = "netlify-plugin-cypress" \ No newline at end of file From 953a81d50241ff25871619b203ffa26dc21d59bc Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Mon, 14 Feb 2022 14:34:07 +0000 Subject: [PATCH 6/6] chore: copy default locale --- demos/base-path/netlify.toml | 4 ++-- demos/static-root/netlify.toml | 4 ++-- src/helpers/files.ts | 25 +++++++++++++------------ src/templates/getHandler.ts | 2 -- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/demos/base-path/netlify.toml b/demos/base-path/netlify.toml index 288149fe89..ce3073f46f 100644 --- a/demos/base-path/netlify.toml +++ b/demos/base-path/netlify.toml @@ -17,5 +17,5 @@ package = "./local-plugin" [[plugins]] package = "@netlify/plugin-local-install-core" -[[context.deploy-preview.plugins]] -package = "netlify-plugin-cypress" \ No newline at end of file +# [[context.deploy-preview.plugins]] +# package = "netlify-plugin-cypress" \ No newline at end of file diff --git a/demos/static-root/netlify.toml b/demos/static-root/netlify.toml index ce3073f46f..288149fe89 100644 --- a/demos/static-root/netlify.toml +++ b/demos/static-root/netlify.toml @@ -17,5 +17,5 @@ package = "./local-plugin" [[plugins]] package = "@netlify/plugin-local-install-core" -# [[context.deploy-preview.plugins]] -# package = "netlify-plugin-cypress" \ No newline at end of file +[[context.deploy-preview.plugins]] +package = "netlify-plugin-cypress" \ No newline at end of file diff --git a/src/helpers/files.ts b/src/helpers/files.ts index 7dcff53738..4e58e7e2d8 100644 --- a/src/helpers/files.ts +++ b/src/helpers/files.ts @@ -241,22 +241,23 @@ export const moveStaticPages = async ({ await writeJson(join(netlifyConfig.build.publish, 'static-manifest.json'), Object.entries(filesManifest)) if (i18n?.defaultLocale) { + const rootPath = basePath ? join(netlifyConfig.build.publish, basePath) : netlifyConfig.build.publish // Copy the default locale into the root - const defaultLocaleDir = join(netlifyConfig.build.publish, i18n.defaultLocale) + const defaultLocaleDir = join(rootPath, i18n.defaultLocale) if (existsSync(defaultLocaleDir)) { - await copy(defaultLocaleDir, `${netlifyConfig.build.publish}/`) + await copy(defaultLocaleDir, `${rootPath}/`) } - const defaultLocaleIndex = join(netlifyConfig.build.publish, `${i18n.defaultLocale}.html`) - const indexHtml = join(netlifyConfig.build.publish, 'index.html') + const defaultLocaleIndex = join(rootPath, `${i18n.defaultLocale}.html`) + const indexHtml = join(rootPath, 'index.html') if (existsSync(defaultLocaleIndex) && !existsSync(indexHtml)) { - try { - await copy(defaultLocaleIndex, indexHtml, { overwrite: false }) - await copy( - join(netlifyConfig.build.publish, `${i18n.defaultLocale}.json`), - join(netlifyConfig.build.publish, 'index.json'), - { overwrite: false }, - ) - } catch {} + await copy(defaultLocaleIndex, indexHtml, { overwrite: false }).catch(() => { + /* ignore */ + }) + await copy(join(rootPath, `${i18n.defaultLocale}.json`), join(rootPath, 'index.json'), { + overwrite: false, + }).catch(() => { + /* ignore */ + }) } } diff --git a/src/templates/getHandler.ts b/src/templates/getHandler.ts index 7d3f20b75d..be2d922858 100644 --- a/src/templates/getHandler.ts +++ b/src/templates/getHandler.ts @@ -85,8 +85,6 @@ const makeHandler = (conf: NextConfig, app, pageRoot, staticManifest: Array<[str } return async function handler(event: HandlerEvent, context: HandlerContext) { - console.log(event) - let requestMode = mode // Ensure that paths are encoded - but don't double-encode them event.path = new URL(event.rawUrl).pathname