Skip to content

Refactor to support custom Next.js distDir#1100

Open
troendheim wants to merge 2 commits intoopennextjs:mainfrom
troendheim:custom-nextjs-distdir
Open

Refactor to support custom Next.js distDir#1100
troendheim wants to merge 2 commits intoopennextjs:mainfrom
troendheim:custom-nextjs-distdir

Conversation

@troendheim
Copy link
Copy Markdown

NextJS allows the configuration of distDir (https://nextjs.org/docs/app/api-reference/config/next-config-js/distDir).
This PR introduces changes needed for the support of this config in open-next.

We will use it to build the same NextJS app (one build dir) with different distDirs simultaneously.

This functionality is already supported in the netlify adapter through opennextjs/opennextjs-netlify@6a35de6 which has been a great inspiration for these changes.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jan 29, 2026

⚠️ No Changeset found

Latest commit: 66342d5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Feb 12, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@opennextjs/aws@1100

commit: 66342d5

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors OpenNext’s build + runtime path handling to support Next.js’ configurable distDir, enabling multiple builds of the same app output with different Next build directories.

Changes:

  • Introduces globalThis.nextDistDir (injected via esbuild banner) and uses it across runtime adapters/handlers.
  • Replaces hardcoded .next paths with options.nextDistDir throughout build/bundling/copy steps.
  • Adds logic to read distDir from next.config.* before running the Next.js build.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
packages/open-next/src/types/global.ts Adds global type for nextDistDir.
packages/open-next/src/plugins/edge.ts Allows edge bundling to target a configurable dist dir.
packages/open-next/src/core/nodeMiddlewareHandler.ts Loads middleware from globalThis.nextDistDir.
packages/open-next/src/build/patch/patches/patchOriginalNextConfig.ts Patches manifests under options.nextDistDir.
packages/open-next/src/build/middleware/buildNodeMiddleware.ts Updates esbuild externals to match nextDistDir.
packages/open-next/src/build/helper.ts Makes normalizeOptions async; reads distDir; injects nextDistDir into esbuild banner.
packages/open-next/src/build/generateOutput.ts Loads Next config from the configured dist dir.
packages/open-next/src/build/edge/createEdgeBundle.ts Uses options.nextDistDir for edge bundle inputs/resources.
packages/open-next/src/build/createServerBundle.ts Updates standalone server paths + traced-file copying for nextDistDir.
packages/open-next/src/build/createRevalidationBundle.ts Copies prerender manifest from nextDistDir.
packages/open-next/src/build/createMiddleware.ts Loads middleware manifest from nextDistDir.
packages/open-next/src/build/createImageOptimizationBundle.ts Copies required server files/BUILD_ID from nextDistDir.
packages/open-next/src/build/createAssets.ts Copies static/cache assets from nextDistDir.
packages/open-next/src/build/copyTracedFiles.ts Adds nextDistDir option to support custom standalone paths.
packages/open-next/src/build.ts Awaits async normalizeOptions.
packages/open-next/src/adapters/image-optimization-adapter.ts Uses globalThis.nextDistDir for runtime config/build ID.
packages/open-next/src/adapters/config/index.ts Uses globalThis.nextDistDir to locate Next artifacts at runtime.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +501 to +505
export async function readDistDirFromConfig(appPath: string): Promise<string> {
const configExt = findNextConfig({ appPath });

if (!configExt) {
return ".next"; // Default
// We need both await here, same way as in https://github.com/opennextjs/opennextjs-aws/pull/704
//@ts-expect-error - This file should be bundled with esbuild
_module = await (await import("./.next/server/middleware.js")).default;
const distDir = globalThis.nextDistDir || ".next";

// Copy over .next/required-server-files.json file and BUILD_ID
fs.mkdirSync(path.join(outputPath, ".next"));
fs.mkdirSync(path.join(outputPath, options.nextDistDir));
Comment on lines 138 to +139
`globalThis.openNextVersion = "${openNextVersion}";`,
`globalThis.nextDistDir = "${nextDistDir}";`,
esbuildOptions.banner?.js || "",
`globalThis.openNextDebug = ${debug};`,
`globalThis.openNextVersion = "${openNextVersion}";`,
`globalThis.nextDistDir = "${nextDistDir}";`,
Comment on lines +551 to +557
// Handle config functions
if (typeof config === "function") {
config = await Promise.resolve(config("phase-production-build", {}));
}

return config?.distDir || ".next";
} catch (error) {
globalThis.__dirname ??= "";

export const NEXT_DIR = path.join(__dirname, ".next");
export const NEXT_DIR = path.join(__dirname, "${distDir}");
Comment on lines 69 to 71
outfile: path.join(outputPath, "handler.mjs"),
external: ["./.next/*"],
external: [`./${options.nextDistDir}/*`],
platform: "node",
plugins: [inlineRequireResolvePlugin],
});

const configModule = await import(compiledPath);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants