Description
I'm using React Router as a...
framework
Reproduction
By opening the network inspector and finding the request to /__manifest?...
, you can note that the Cache-Control
header is set to public, max-age=31536000, immutable
- this is set in the server runtime here:
react-router/packages/react-router/lib/server-runtime/server.ts
Lines 334 to 338 in 796e9ae

System Info
System:
OS: macOS 15.3.1
CPU: (10) arm64 Apple M1 Max
Memory: 3.90 GB / 32.00 GB
Shell: 5.9 - /opt/homebrew/bin/zsh
Binaries:
Node: 22.12.0 - ~/.n/bin/node
npm: 10.9.0 - ~/.n/bin/npm
pnpm: 9.6.0 - ~/.n/bin/pnpm
bun: 1.2.4 - /opt/homebrew/bin/bun
Browsers:
Chrome: 134.0.6998.44
Edge: 134.0.3124.51
Safari: 18.3
npmPackages:
@react-router/dev: ^7.0.0 => 7.3.0
@react-router/express: ^7.0.0 => 7.3.0
@react-router/fs-routes: ^7.0.0 => 7.3.0
@react-router/node: ^7.0.0 => 7.3.0
@react-router/serve: ^7.0.0 => 7.3.0
react-router: ^7.0.0 => 7.3.0
vite: ^6.2.1 => 6.2.1
Used Package Manager
pnpm
Expected Behavior
I'm not sure the original intention of Cache-Control
header here, but doing so causes CDNs like CloudFront to cache the response which introduces two issues:
- After deploying a new application version, client-side navigation can break as stale versions of the manifest can be served. If the new/old pages have incompatible dependencies (e.g. upgrading React versions), this can break navigation in unexpected ways. This can also break the route discovery itself, leading to client-side navigations that return 404, but resolve on refresh.
- The recent PR Detect lazy route discovery manifest version mismatches and trigger reloads #13061 introduced detection for manifest version mismatches, however these mismatches are never detected with the indefinite cache header. Instead, the first request for that manifest/version is cached, and subsequent requests to that same path return the original cached response and are not able to reach the origin and evaluate the check for version skew.
Based on my understanding of the purpose of this manifest, I would expect it not to have a Cache-Control
header at all, so that it can be properly evaluated when requested by the client.
Actual Behavior
The Cache-Control
header is set to public, max-age=31536000, immutable
and CDNs (like CloudFront) will indefinitely cache this response.