AWS
Full Example

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;