Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .changeset/fix-preview-props-manifest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@opennextjs/cloudflare": patch
---

fix(patches): include `preview-props.json` in loadManifest build-time inlining

Next.js 16.4 moved preview props out of `prerender-manifest.json` into a standalone
`.next/server/preview-props.json` (`PREVIEW_PROPS_MANIFEST`), loaded unconditionally by
`NextNodeServer.getPreviewProps()` from the `Server` constructor. The file exists in the build
output but wasn't matched by the glob pattern `*-manifest.json`, so the patched `loadManifest()`
threw at runtime and every dynamic route returned a 500.

It is inlined rather than falling back to `{}` because it holds the actual draft-mode
id and signing/encryption keys.
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ async function getLoadManifestRule(buildOpts: BuildOptions) {
const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts));
const dotNextDir = join(baseDir, ".next");

// Most server manifests are named `*-manifest.json`, but a few are not:
// `required-server-files.json`, `prefetch-hints.json` (Next 16.2+) and
// `server/preview-props.json` (Next 16.4+, previously inlined in the
// prerender manifest). They are loaded unconditionally by `NextNodeServer`,
// so they must be inlined rather than falling back to `{}`.
const manifests = await glob(
join(dotNextDir, "**/{*-manifest,required-server-files,prefetch-hints}.json"),
join(dotNextDir, "**/{*-manifest,required-server-files,prefetch-hints,preview-props}.json"),
{
windowsPathsNoEscape: true,
}
Expand Down