Skip to content

fix(app-router): send anonymous crossOrigin on dynamic preloads and bootstrap hints - #3327

Open
snhsish wants to merge 1 commit into
cloudflare:mainfrom
snhsish:fix/dynamic-preload-crossorigin-3326
Open

snhsish wants to merge 1 commit into
cloudflare:mainfrom
snhsish:fix/dynamic-preload-crossorigin-3326

Conversation

@snhsish

@snhsish snhsish commented Sep 18, 2026

Copy link
Copy Markdown

Fixes #3326.

With a cross-origin assetPrefix (e.g. R2/CDN) that only returns ACAO when Origin is set, a preload fetched without CORS caches a non-CORS response; the later CORS module or stylesheet fetch then fails and the boundary errors.

Changes

  • DynamicPreloadChunks: stylesheet links now carry anonymous crossOrigin (JS modulepreload already had it). Keeps the intentional no-as="style" divergence.
  • app-ssr-entry.ts: same CORS-cache class fixed in the bootstrap hints — preinitModule(appBootstrapPreinitModules) passes crossOrigin: "", the manual bootstrap modulepreload link emits crossorigin="", and React's bootstrapModules is now passed as { src, crossOrigin: "" } descriptors so both its preload link and script tag carry CORS.
  • Tests: crossorigin assertions for same-origin CSS, /cdn path-prefix JS, and absolute-https://cdn.example.com (every CDN modulepreload/stylesheet hint plus the dynamic stylesheet path).

Same-origin behavior is unchanged (anonymous CORS is a no-op there) and nonce/CSP paths are untouched — covered by the existing nonce assertions in the same tests.

Validation

  • pnpm run check green (fmt, lint, types, shim-type sync)
  • tests/app-router-production-server.test.ts: 16 dynamic tests + both assetPrefix tests pass
  • tests/asset-prefix.test.ts (47), use-client-page-pathname (11), script-head-ordering (8) pass
  • Full Vitest + Playwright left for CI per repo norms

Note: #3314 touches adjacent lines in dynamic-preload-chunks.tsx (CSS dedup); happy to rebase whichever lands second — the changes compose.

…ootstrap hints

With a cross-origin assetPrefix that only returns ACAO when Origin is
set, a preload fetched without CORS caches a non-CORS response and the
later CORS module or stylesheet fetch fails.

Fixes cloudflare#3326
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.

App Router: next/dynamic asset preloads omit crossOrigin with external assetPrefix

1 participant