Skip to content

fix(deploy): plain-text 404 for invalid _next/static in Pages Router worker#1630

Merged
james-elicx merged 1 commit into
mainfrom
fix/issue-1337-next-static-plain-404
May 28, 2026
Merged

fix(deploy): plain-text 404 for invalid _next/static in Pages Router worker#1630
james-elicx merged 1 commit into
mainfrom
fix/issue-1337-next-static-plain-404

Conversation

@james-elicx

Copy link
Copy Markdown
Member

Summary

  • The Pages Router Cloudflare worker template generated by vinext deploy was forwarding asset-shaped misses (e.g. /_next/static/nonexistent.js) to renderPage, which renders the full HTML 404 page with bootstrap scripts + CSS instead of the plain-text "Not Found" body Next.js emits.
  • Adds the existing isNextStaticPath + notFoundStaticAssetResponse short-circuit (already used by app-router-entry, prod-server App Router branch, and prod-server Pages Router branch) to generatePagesRouterWorkerEntry() so invalid _next/static/* requests — including those under basePath or assetPrefix — return text/plain; charset=utf-8 "Not Found" before the renderer runs.
  • Matches Next.js behaviour in packages/next/src/server/lib/router-server.ts.

Fixes #1337

Test plan

  • pnpm test tests/deploy.test.ts — new regression test asserts the generated Pages Router worker contains the short-circuit and that it precedes the renderPage call.
  • pnpm test tests/invalid-static-asset-404.test.ts — existing end-to-end assertions for the App Router worker entry + prod server (Node) still pass.
  • pnpm test tests/after-deploy.test.ts — generator metadata tests still pass.
  • pnpm run lint, pnpm run fmt:check.

…worker

The Pages Router Cloudflare worker template generated by `vinext deploy`
forwarded asset-shaped misses to `renderPage`, which renders the full
HTML 404 page (with bootstrap scripts + CSS) instead of the plain-text
"Not Found" body Next.js emits. The App Router worker entry and prod
server already short-circuit these requests; only the Pages Router
worker template was missing the check.

Adds `isNextStaticPath` + `notFoundStaticAssetResponse` to
`generatePagesRouterWorkerEntry()` so invalid `_next/static/*` requests
(including those under `basePath` or `assetPrefix`) return
`text/plain; charset=utf-8` "Not Found" before the renderer runs.

Matches Next.js: packages/next/src/server/lib/router-server.ts.

Fixes #1337
@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review

@pkg-pr-new

pkg-pr-new Bot commented May 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/vinext@1630

commit: a683aad

@github-actions

Copy link
Copy Markdown
Contributor
Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original
web preview production

@ask-bonk ask-bonk Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Clean, well-scoped fix. The change is a straightforward port of the existing isNextStaticPath + notFoundStaticAssetResponse short-circuit pattern to the one remaining code path that was missing it.

Correctness: The placement mirrors app-router-entry.ts exactly — after isOpenRedirectShaped but before filterInternalHeaders / basePath stripping / middleware. This is the right spot: _next/static/* requests never need middleware processing, and the check uses the raw pathname (before basePath is stripped) which is correct since isNextStaticPath handles basePath stripping internally.

Parity check: Verified the same pattern exists in:

  • server/app-router-entry.ts:89-96 — App Router worker entry ✓
  • server/prod-server.ts:1166-1178 — App Router prod server (via resolveAppRouterAssetPath) ✓
  • server/prod-server.ts:1514-1527 — Pages Router prod server (via resolveAppRouterAssetPath) ✓

The Pages Router worker template in deploy.ts was indeed the only remaining gap.

Generated entry stays thin: The new code delegates entirely to existing typed helpers (isNextStaticPath, notFoundStaticAssetResponse, assetPrefixPathname) — no inline logic added. Consistent with the AGENTS.md guidance.

Tests: The positional assertion (staticPos < renderPagePos) is a good pattern already used by other tests in this file (e.g., the requestContextFromRequestrunMiddleware ordering test at line 920). Import presence checks are reasonable for generated code tests.

@ask-bonk

ask-bonk Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Approved PR #1630. The fix is correct and well-implemented:

  • One-line summary: The Pages Router Cloudflare worker template was the only remaining code path missing the _next/static/* plain-text 404 short-circuit. This PR adds it using the same helpers already used by the App Router worker entry and both prod server branches.
  • Placement is correct — after open-redirect detection, before middleware/basePath stripping, matching the App Router entry exactly.
  • Follows the "thin entry" principle — delegates to existing typed helpers, no inline logic.
  • Tests are solid — import checks + positional ordering assertion, consistent with other tests in the file.

github run

@james-elicx
james-elicx marked this pull request as ready for review May 28, 2026 11:07
@james-elicx
james-elicx merged commit fc31708 into main May 28, 2026
38 checks passed
@james-elicx
james-elicx deleted the fix/issue-1337-next-static-plain-404 branch May 28, 2026 13:04
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.

Invalid _next/static paths should return plain text 404, not rendered HTML

1 participant