diff --git a/README.md b/README.md index 60baf6aee2..10d4189b48 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ # Essential Next.js Build Plugin (beta) - -:warning: This is the beta version of the Essential Next.js plugin. For the stable version, see [Essential Next.js plugin v3](https://github.com/netlify/netlify-plugin-nextjs/tree/v3#readme) :warning: +:warning: This is the beta version of the Essential Next.js plugin. For the stable version, refer to +[Essential Next.js plugin v3](https://github.com/netlify/netlify-plugin-nextjs/tree/v3#readme) :warning:

@@ -16,16 +16,19 @@ ## What's new in this version -Version 4 is a complete rewrite of the Essential Next.js plugin. For full details of everything that's new, see [the v4 release notes](https://github.com/netlify/netlify-plugin-nextjs/blob/main/docs/release-notes/v4.md) +Version 4 is a complete rewrite of the Essential Next.js plugin. For full details of everything that's new, check out +[the v4 release notes](https://github.com/netlify/netlify-plugin-nextjs/blob/main/docs/release-notes/v4.md) ## Installing the beta - - Install the module: + ```shell npm install -D @netlify/plugin-nextjs@beta ``` -- Change the `publish` directory to `.next` and add the plugin to `netlify.toml` if not already installed: + +- Change the `publish` directory to `.next` and add the plugin to `netlify.toml` if not already installed: + ```toml [build] publish = ".next" @@ -34,16 +37,27 @@ publish = ".next" package = "@netlify/plugin-nextjs" ``` -If you previously set a custom `distDir` in your `next.config.js`, or set `node_bundler` or `external_node_modules` in your `netlify.toml` these are no longer needed and can be removed. +If you previously set a custom `distDir` in your `next.config.js`, or set `node_bundler` or `external_node_modules` in +your `netlify.toml` these are no longer needed and can be removed. + +The `serverless` and `experimental-serverless-trace` targets are deprecated in Next 12, and all builds with this plugin +will now use the default `server` target. If you previously set the target in your `next.config.js`, you should remove +it. -The `serverless` and `experimental-serverless-trace` targets are deprecated in Next 12, and all builds with this plugin will now use the default `server` target. If you previously set the target in your `next.config.js`, you should remove it. +If you are using a monorepo you will need to change `publish` to point to the full path to the built `.next` directory, +which may be in a subdirectory. If you have changed your `distDir` then it will need to match that. -If you are using a monorepo you will need to change `publish` to point to the full path to the built `.next` directory, which may be in a subdirectory. If you have changed your `distDir` then it will need to match that. +If you are using Nx, then you will need to point `publish` to the folder inside `dist`, e.g. `dist/apps/myapp/.next`. -If you are using Nx, then you will need to point `publish` to the folder inside `dist`, e.g. `dist/apps/myapp/.next`. +If you currently use redirects or rewrites on your site, see +[the Rewrites and Redirects guide](https://github.com/netlify/netlify-plugin-nextjs/blob/main/docs/redirects-rewrites.md) +for information on changes to how they are handled in this version. -If you currently use redirects or rewrites on your site, see [the Rewrites and Redirects guide](https://github.com/netlify/netlify-plugin-nextjs/blob/main/docs/redirects-rewrites.md) for information on changes to how they are handled in this version. +If you want to use Next 12's beta Middleware feature, this will mostly work as expected but please +[read the docs on some caveats and workarounds](https://github.com/netlify/netlify-plugin-nextjs/blob/main/docs/middleware.md) +that are currently needed. ## Beta feedback -Please share any thoughts, feedback or questions about the beta [in our discussion](https://github.com/netlify/netlify-plugin-nextjs/discussions/706). +Please share any thoughts, feedback or questions about the beta +[in our discussion](https://github.com/netlify/netlify-plugin-nextjs/discussions/706). diff --git a/docs/middleware.md b/docs/middleware.md new file mode 100644 index 0000000000..c93ccbe97a --- /dev/null +++ b/docs/middleware.md @@ -0,0 +1,76 @@ +# Using Next 12 middleware on Netlify + +Next 12 introduces a new feature called [Middleware](https://nextjs.org/docs/middleware), in which functions +run before a request has finished processing. Middleware can be used to modify the request or replace the response. For +example, it can change headers, rewrite the request path, or return a different response entirely. + +Next.js Middleware can run either in an edge function or at the origin. On Netlify, middleware runs at the origin as part +of the normal Next.js server. + +## How to deploy Next 12 middleware + +Next 12 Middleware works out of the box with Netlify, and most functions will work unchanged. See +[the middleware docs](https://nextjs.org/docs/middleware) for details of how to create them. There are however a few +workarounds that are currently required for some features during the beta period: + +### `geo` + +When running at the origin, Next.js does not populate the `request.geo` object. Fortunately there is a one line fix to get +the visitor's country: + +```typescript +export async function middleware(req: NextRequest) { + // Add this line + req.geo.country = req.headers.get('x-country') + + // The rest of your middleware goes here +} +``` + +### `ip` + +Next.js also does not populate the `req.ip` value when running at the origin. There is another one line fix for this: + +```typescript +export async function middleware(req: NextRequest) { + // Add this line + req.ip = req.headers.get('x-nf-client-connection-ip') + + // The rest of your middleware goes here +} +``` + +## Caveats + +Because the middleware runs at the origin, it is run _after_ Netlify rewrites and redirects. If a static file is served by the Netlify CDN +then the middleware is never run, as middleware only runs when a page is served by Next.js. This means that middleware should not be used with the +`EXPERIMENTAL_MOVE_STATIC_FILES` option, as this causes statically-generated pages to be served by the Netlify CDN +before any middleware can be run. + +There is currently [a bug in Next.js](https://github.com/vercel/next.js/issues/31179) that causes a proxy loop if you +try to rewrite to a URL with a host other than localhost. If you are using a pattern like this: + +```typescript +export function middleware(req: NextRequest) { + // Change the `nextUrl` property in some way + req.nextUrl = req.nextUrl.replace('something', 'somethingelse') + // ...then rewrite to the changed URL + return NextResponse.rewrite(req.nextUrl) +} +``` + +...then you need to set the `nextUrl.host` to `localhost`: + +```typescript +export function middleware(req: NextRequest) { + // Change the `nextUrl` property in some way + req.nextUrl = req.nextUrl.replace('something', 'somethingelse') + req.nextUrl.host = 'localhost' + + // ...then rewrite to the changed URL + return NextResponse.rewrite(req.nextUrl) +} +``` + +If you have an issue with Next.js middleware on Netlify while it is beta, particularly if the issue cannot be reproduced when +running locally, then please add a comment to [the Next plugin beta discussion](https://ntl.fyi/next-beta-feedback).