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 (require to use @opennextjs/cloudflare
).
For more information about the options here, take a look at the reference section.
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
// You don't have to provide the below, by default it will generate an output
// for normal lambda as in open-next v2
override: {
// 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
},
}),
},
// 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
},
// Below we define the functions that we want to deploy in a different server
// This is only used if you want to split the server into multiple servers
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 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",
},
// 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, // deprecated and not supported in next 14.2+
},
pageSsr: {
// 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"],
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
// 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: {},
},
},
// By setting this, it will create another bundle for the middleware,
// and the middleware will be deployed in a separate server.
// If not set middleware will be bundled inside the servers
// It could be in lambda@edge, cloudflare workers, or anywhere else
// By default it uses lambda@edge
// 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,
},
// Optional
imageOptimization: {
loader: "s3-lite", // Can be overridden with a LazyLoadedOverride
// This is necessary to bundle the proper version of sharp
// 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 'skipping build'",
dangerous: {
// This will disable the tag cache
// You can use it safely on page router, on app router it will break revalidateTag and revalidatePath
disableTagCache: true,
// 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,
// 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;