diff --git a/pages/aws/config/full_example.mdx b/pages/aws/config/full_example.mdx index 1415679..b99e963 100644 --- a/pages/aws/config/full_example.mdx +++ b/pages/aws/config/full_example.mdx @@ -1,24 +1,40 @@ -Here is a detailed example of an `open-next.config.ts` file: -This file need to be at the same place as your `next.config.js` file +Here is a detailed example of an `open-next.config.ts` file. This file need to be at the same place as your `next.config.js` file -`server` in here could refer to a lambda function, a docker container, a node server or whatever that can support running nodejs code. (Even cloudflare workers in the future) +`server` in here could refer to a lambda function, a docker container, a node server or whatever that can support running nodejs code. Even Cloudflare workers (require to use `@opennextjs/cloudflare`). -For more information about the options here, take a look at the [components section](/aws/components/overview). +For more information about the options here, take a look at the [reference section](/aws/config/reference). ```ts -import type { OpenNextConfig } from '@opennextjs/aws/types/open-next.js' +import type { OpenNextConfig } from '@opennextjs/aws/types/open-next'; const config = { - default: { // This is the default server, similar to the server-function in open-next v2 + default: { + // This is the default server, similar to the server-function in open-next v2 // You don't have to provide the below, by default it will generate an output // for normal lambda as in open-next v2 override: { - wrapper: "aws-lambda-streaming", // This is necessary to enable lambda streaming + // This is necessary to enable lambda streaming, defaults to aws-lambda + wrapper: 'aws-lambda-streaming', + // Convert the input and output of the server, defaults to aws-apigw-v2 + converter: 'aws-apigw-v2', + // Used for fetch cache and html/rsc/json cache, defaults to s3 + incrementalCache: 's3', + // Used for external rewrites, defaults to node + proxyExternalRequest: 'node', + tagCache: 'dynamodb', // Used for revalidatePath and revalidateTag, defaults to dynamodb // You can override any part that is a `LazyLoadedOverride` this way - queue: () => Promise.resolve({ - send: async (message) => { - //Your custom code here - } - }) + queue: () => + Promise.resolve({ + send: async (message) => { + //Your custom code here + }, + }), + }, + // this will install sharp to your default server function + // only for example purposes, you most likely should not use this + // this can be used on every server to install additional packages + install: { + packages: ['sharp@0.33.5'], + arch: 'arm64', }, minify: true, // This will minify the output }, @@ -27,36 +43,44 @@ const config = { functions: { ssr: { routes: [ - "app/api/isr/route", "app/api/sse/route", "app/api/revalidateTag/route", // app dir Api routes - "app/route1/page", "app/route2/page", // app dir pages - "pages/route3" // page dir pages - ], // For app dir, you need to include route|page, no need to include layout or loading - patterns: ['api/*', 'route1', 'route2', 'route3'], // patterns needs to be in a cloudfront compatible format, this will be used to generate the output + 'app/api/isr/route', + 'app/api/sse/route', + 'app/api/revalidateTag/route', // app dir Api routes + 'app/route1/page', + 'app/route2/page', // app dir pages + 'pages/route3', // page dir pages + ], // For app dir, you need to include route|page, no need to include layout or loading + // patterns needs to be in a cloudfront compatible format + // this will be used to generate the output + patterns: ['api/*', 'route1', 'route2', 'route3'], override: { - wrapper: "aws-lambda-streaming", + wrapper: 'aws-lambda-streaming', }, // This enables the bundled next server which is faster and reduce the size of the server // This is also experimental and might not work in all cases - experimentalBundledNextServer: true + experimentalBundledNextServer: true, // deprecated and not supported in next 14.2+ }, pageSsr: { - routes: ["pages/pageSsr"], // For page dir routes should be in the form `pages/${route}` without the extension, it should match the filesystem + // For page dir routes should be in the form `pages/${route}` without the extension + // It should match the filesystem + routes: ['pages/pageSsr'], // BUILD_ID is a special case, it will be replaced with the actual build id - patterns: [ 'pageSsr', "_next/data/BUILD_ID/pageSsr.json"], + patterns: ['pageSsr', '_next/data/BUILD_ID/pageSsr.json'], override: { - wrapper: "node", - converter: "node", - // This is necessary to generate the dockerfile and for the implementation to know that it needs to deploy on docker + wrapper: 'node', + converter: 'node', + // This is necessary to generate the dockerfile and + // for the implementation to know that it needs to deploy on docker // You can also provide a string here which will be used to create the dockerfile generateDockerfile: true, }, }, edge: { - runtime: "edge", - routes: ["app/ssr/page"], - patterns: ["ssr"], - override: {} - } + runtime: 'edge', + routes: ['app/ssr/page'], + patterns: ['ssr'], + override: {}, + }, }, // By setting this, it will create another bundle for the middleware, // and the middleware will be deployed in a separate server. @@ -66,19 +90,48 @@ const config = { // This is not implemented in the reference construct implementation. // This is optional, but might be necessary if you split your app into multiple servers middleware: { - external: true - } - + external: true, + }, // Optional imageOptimization: { - // This is the architecture of the image, it could be x64 or arm64 + loader: "s3-lite", // Can be overridden with a LazyLoadedOverride // This is necessary to bundle the proper version of sharp - arch: "x64", - } - + // You can customize this to your needs + // By default it will install with these options: + install: { + packages: ['sharp@0.32.6'], + arch: 'arm64', + nodeVersion: '18', + libc: 'glibc', + }, + }, + // Initialization function is a special server that will run at build time to initialize the cache. + // By default, it only initializes the tag cache. Besides the common options, you can use the following options: + initializationFunction: { + tagCache: 'dynamodb-lite', // Can be overridden with a LazyLoadedOverride + }, + // Override the default revalidate function + // By default, works for lambda and on SQS event. + // Supports only node runtime + revalidate: { + override: { + wrapper: 'aws-lambda', // Can be overridden with a LazyLoadedOverride + converter: 'aws-apigw-v2', // Can be overridden with a LazyLoadedOverride + }, + }, + // Override the default warmer + // By default, works for lambda only. + // If you override this, you'll need to handle the warmer event in the wrapper + warmer: { + invokeFunction: 'aws-lambda', // Can be overridden with a LazyLoadedOverride + override: { + wrapper: 'aws-lambda', // Can be overridden with a LazyLoadedOverride + converter: 'aws-apigw-v2', // Can be overridden with a LazyLoadedOverride + }, + }, // If you want to override the default build command, you can do it here // By default it uses `npm run build` - buildCommand: "echo 'hello world'", + buildCommand: "echo 'skipping build'", dangerous: { // This will disable the tag cache @@ -87,19 +140,38 @@ const config = { // This will disable the incremental cache // This is generally not recommended, as this is necessary for ISR AND SSG routes as well as the fetch cache disableIncrementalCache: true, - } - - //The path to the target folder of build output from the `buildCommand` option (the path which will contain the `.next` and `.open-next` folders). This path is relative from the current process.cwd() - Optional default to "." - buildOutputPath: "build", - - //The path to the root of the Next.js app's source code. This path is relative from the current process.cwd(). - Optional default to "." - appPath: "app", - - //The path to the package.json file of the Next.js app. This path is relative from the current process.cwd(). - Optional - packageJsonPath: "package.json", - -} satisfies OpenNextConfig + // Enable the cache interception. Every request will go through the cache interceptor, if it is found in the cache, + // it will be returned without going through NextServer. Not every feature is covered by the cache interceptor and + // it should fallback to the NextServer if the cache is not found. + enableCacheInterception: true, + // Function to determine which headers or cookies takes precedence. + // By default, the middleware headers and cookies will override the handler headers and cookies. + // This is executed for every request and after next config headers and middleware has executed. + // Here is a very simple example of how you can use it: + headersAndCookiesPriority: (event) => { + if (event.rawPath.startsWith('/api')) { + return 'middleware'; + } + return 'handler'; + }, + }, + // The path to the target folder of build output from the `buildCommand` option + // (the path which will contain the `.next` and `.open-next` folders). + // This path is relative from the current process.cwd() - Optional defaults to "." + buildOutputPath: 'build', + // The path to the root of the Next.js app's source code. + // This path is relative from the current process.cwd(). - Optional defaults to "." + appPath: 'app', + // The path to the package.json file of the Next.js app. + // This path is relative from the current process.cwd(). - Optional + packageJsonPath: 'package.json', + // Advanced usage + // If you use the edge runtime somewhere (either with an external middleware or in the functions), we compile 2 versions of the open-next.config.ts file. + // One for the node runtime and one for the edge runtime. + // This option allows you to specify the externals for the edge runtime used in esbuild for the compilation of open-next.config.ts + // It is especially useful if you use some custom overrides only in node + edgeExternals: [], +} satisfies OpenNextConfig; export default config; -export type Config = typeof config ``` \ No newline at end of file diff --git a/pages/aws/config/nx.mdx b/pages/aws/config/nx.mdx index 0493b2a..e9334a8 100644 --- a/pages/aws/config/nx.mdx +++ b/pages/aws/config/nx.mdx @@ -1,7 +1,7 @@ # Configuring OpenNext for use in an Nx Monorepo. -Here's a detailed exampled of how to add open-next + SST to an existing Nx workspace, with an existing NextJS application sitting at `apps/next-site` +Here's a detailed exampled of how to add OpenNext + SST to an existing Nx workspace, with an existing NextJS application sitting at `apps/next-site` -1. install `open-next`: `pnpm add —save-dev open-next` +1. install `open-next`: `pnpm add —save-dev @opennextjs/aws` 2. Update your `apps/next-site/next.config.js` add `output: ‘standalone’`, and you want to add `experimental.outputFileTracingRoot`, it should look a little like this: ```javascript @@ -35,9 +35,9 @@ const plugins = [ module.exports = composePlugins(...plugins)(nextConfig); ``` -3. Create `open-next.config.js` inside your apps root directory, it should look a little something like this: +3. Create `open-next.config.ts` inside your apps root directory, it should look a little something like this: ```javascript -import type { OpenNextConfig } from '@opennextjs/aws/types/open-next.js'; +import type { OpenNextConfig } from '@opennextjs/aws/types/open-next'; const config = { default: {}, @@ -122,7 +122,7 @@ now, when you run `nx open-next-build next-site`, nx will automatically build th Now, we have a built app, ready to deploy, so how do we get it onto SST/AWS ? Good question! -We are using `sst ion` in this example. i will assume you have already have the cli installed, (if not, check here on how!)[https://ion.sst.dev/], +We are using `sst ion` in this example. i will assume you have already have the cli installed, [if not, check here on how](https://sst.dev), but we will not use the SST cli to init this project, because it wants to add a package.json to your next app, and it will look like it's working, but you will end up with a big far server error (all because the package.json overrides whatever nx _thinks_ there should be, and it will miss a bunch of dependencies). we will instead manually set this up: - let's add the sst package with `pnpm add sst@ion`, and the required packages for SST to work with AWS `pnpm add --save-dev aws-cdk-lib constructs @types/aws-lambda` diff --git a/pages/aws/config/reference.mdx b/pages/aws/config/reference.mdx index ce2cc89..99e20da 100644 --- a/pages/aws/config/reference.mdx +++ b/pages/aws/config/reference.mdx @@ -1,6 +1,8 @@ Every option that you can use in `open-next.config.ts` will be listed here. This is the configuration file that you can use to customize the build. You can look at the [full example](full_example) to see how you can use these options. +
+ import { Tabs } from 'nextra/components' @@ -24,7 +26,7 @@ import { Tabs } from 'nextra/components' ### `minify` - This will try to minify the output of the server including node_modules. It is a boolean and by default, it is set to `false`. + This will try to minify the output of the server including `node_modules`. It is a boolean and by default, it is set to `false`. It could lead to some issues with some packages, so it is recommended to test your app with this option before deploying it. We will likely not fix issues related to this option, as it is usually library specific. @@ -32,18 +34,14 @@ import { Tabs } from 'nextra/components' ### `override` This is where you will be able to override some part of the server. For all of them you can provide what we call a `LazyLoadedOverride` which is a function that will return the override. For some example look at some [Custom overrides](custom_overrides). - All servers have some default override that you can override - - TODO: Add all the types for the custom LazyLoadedOverride here. In the meantime, just look at the [source file](https://github.com/opennextjs/opennextjs-aws/blob/main/packages/open-next/src/types/open-next.ts) - - --- + All servers have some default override that you can override. You can look at the types [here](https://github.com/opennextjs/opennextjs-aws/blob/5b314b13b2907a4510e7f0cca6959f8da4eab310/packages/open-next/src/types/overrides.ts). #### [`wrapper`](overrides/wrapper) This is the entrypoint of the server. Be aware that it might not be enough to change this to make it work on said platform. This is only the entrypoint, you might need to change other parts of the server to make it work on the platform. - Possible values are: `aws-lambda`, `aws-lambda-streaming`, `node`, `cloudflare`, `dummy` or a `LazyLoadedOverride` that will return the wrapper. + Possible values are: `aws-lambda`, `aws-lambda-streaming`, `cloudflare-edge`, `cloudflare-node`, `node`, `express-dev`, `dummy` or a `LazyLoadedOverride` that will return the wrapper. #### [`converter`](overrides/converter) @@ -53,7 +51,7 @@ import { Tabs } from 'nextra/components' #### `install` - Install options for the server. This is used to install additional packages to this server + Install options for the server. This is used to install additional packages. It is an object with the options below. For image optimization, it will install sharp by default @@ -68,7 +66,35 @@ import { Tabs } from 'nextra/components' Possible values are: `x64`, `arm64` - TODO: Add the other options and explain how to install packages on the default or splitted server functions + ##### `nodeVersion` + + This option will be passed to the postinstall script of sharp. It is used by `node-gyp`. + + ##### `libc` + + Override libc of native modules to install. + + Possible values are: `glibc`, `musl` + + ##### `additionalArgs` + + Additional arguments to pass to the install command (npm install). It is a string that will get appended to the `npm install` command. + + Here is an example of how to install sharp on your default server function with ARM64 architecture: + ```ts + import type { OpenNextConfig } from '@opennextjs/aws/types/open-next'; + const config = { + default: { + install: { + packages: ['sharp@0.33.5'], + arch: 'arm64', + }, + }, + } satisfies OpenNextConfig; + + export default config; + ``` + @@ -103,13 +129,13 @@ import { Tabs } from 'nextra/components' Add possibility to override the default s3 cache. Used for fetch cache and html/rsc/json cache. - Possible values are: `s3`, `s3-lite`, `dummy` or a `LazyLoadedOverride` that will return the incremental cache. + Possible values are: `s3`, `s3-lite`, `multi-tier-ddb-s3`, `fs-dev`, `dummy` or a `LazyLoadedOverride` that will return the incremental cache. #### [`tagCache`](overrides/tag_cache) Add possibility to override the default tag cache. Used for revalidateTags and revalidatePath. - Possible values are: `dynamodb`, `dynamodb-lite`, `dummy` or a `LazyLoadedOverride` that will return the tag cache. + Possible values are: `dynamodb`, `dynamodb-lite`, `fs-dev`, `dummy` or a `LazyLoadedOverride` that will return the tag cache. #### [`queue`](overrides/queue) @@ -122,6 +148,12 @@ import { Tabs } from 'nextra/components' Add possibility to override the default proxy for external request (i.e. next config external rewrites or middleware rewrites). Used in the external middleware or one of the server function. Possible values are: `node`, `fetch`, `dummy` or a `LazyLoadedOverride` that will return the proxy. Default is `node` + + #### [`cdnInvalidation`](overrides/automatic_cdn_invalidation) + + Add possibility to override the CDN invalidation override. Used for on-demand invalidation with `revalidatePath()`, `revalidateTag()` and `res.revalidate()`. + + Possible values are: `cloudfront`, `dummy` or a `LazyLoadedOverride` that will return the invalidatePaths. This override is disabled by default. Every splitted server will have the same options as the default server. In addition to that, you can use the following options: @@ -173,7 +205,7 @@ import { Tabs } from 'nextra/components' ### [`loader`](overrides/image_loader) The image loader is used to load the image from the source. - Possible values are: `s3`, `host`, `dummy` or a `LazyLoadedOverride` that will return the loader. + Possible values are: `s3`, `s3-lite`, `host`, `fs-dev`, `dummy` or a `LazyLoadedOverride` that will return the loader. Revalidate doesn't have any specific options. It only uses the common options. @@ -195,7 +227,7 @@ import { Tabs } from 'nextra/components' Add possibility to override the default tag cache used for the initialization function. - Possible values are: `dynamodb`, `dynamodb-lite`, `dummy` or a `LazyLoadedOverride` that will return the tag cache. + Possible values are: `dynamodb`, `dynamodb-lite`, `fs-dev`, `dummy` or a `LazyLoadedOverride` that will return the tag cache. @@ -239,14 +271,12 @@ It is also the place where you could find some experimental features. --- - #### `disableTagCache` This will disable the tag cache. You can disable it safely if you only use page router. It is used for `revalidateTag` and `revalidatePath`. It's a boolean and by default, it is set to `false`. - #### `disableIncrementalCache` This will disable the incremental cache. It is generally not recommended, as this is necessary for ISR **AND** SSG routes as well as the fetch cache. @@ -254,7 +284,7 @@ It's a boolean and by default, it is set to `false`. #### `enableCacheInterception` - Experimental -This will enable cache interception. It will allow you to intercept the cache system directly inside OpenNext routing layer and serve the page directly from the cache without going through `NextServer`. +This will enable cache interception. It will allow you to intercept the cache system directly inside OpenNext routing layer and serve the page directly from the cache without going through `NextServer`. If the cache interception fail, the request will be forwarded to the `NextServer` as usual.