Description
Link to the code that reproduces this issue
https://codesandbox.io/p/devbox/next-js-rsc-cache-busting-redirect-not-working-5psn4k
To Reproduce
- Open the homepage of this repro sandbox.
The next.config.js
file is configured as
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
reactStrictMode: true,
async redirects() {
return [
{
source: "/fake-path",
destination: "/real-path",
permanent: true,
},
];
},
};
export default nextConfig;
- Click "Go to Fake Path." This triggers a redirect from /fake-path to /real-path.
- Observe that the ?_rsc query parameter is missing in the redirected request.
fetch /fake-path?_rsc=xxx and 308 to /real-path without query
Following the redirect, fetch /real-path again, it's text/x-component RSC
response but there's no ?_rsc=xxx query busting. This make local browser or some CDN providers hard to distinguish "HTML Web Page" and "RSC Component Response".
I can confirm this can happen to browser in bf cache.
Current vs. Expected behavior
Current
308 Redirected RSC requests ?_rsc=xxx
doesn't forward.
Expected
308 Redirected RSC request should also contain ?_rsc=xxx query to help Browser / CDN to separate cache.
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP PREEMPT_DYNAMIC Sun Aug 6 20:05:33 UTC 2023
Available memory (MB): 4242
Available CPU cores: 2
Binaries:
Node: 20.9.0
npm: 9.8.1
Yarn: 1.22.19
pnpm: 8.10.2
Relevant Packages:
next: 15.2.2-canary.4 // Latest available version is detected (15.2.2-canary.4).
eslint-config-next: N/A
react: 19.0.0
react-dom: 19.0.0
typescript: 5.3.3
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Dynamic Routes, Redirects, Route Handlers
Which stage(s) are affected? (Select all that apply)
next dev (local), next start (local), Other (Deployed), Vercel (Deployed), next build (local)
Additional context
Suspected Cause
I suspect this issue was introduced in #51195
It seems that the following code is intended to remove the ?_rsc
query parameter when redirecting to a page router. However, in this case, the target destination is an app router, meaning the ?_rsc
query should not have been removed.
Real-world Impact
This issue has also been observed on Cursor’s official website.
As shown below, the "200 OK (from disk cache)" response indicates that the browser is caching and serving an RSC response instead of a normal HTML page. While the browser correctly renders the cached content as-is, the problem arises because RSC responses are not meant to be directly presented to users. Without the proper client-side cache separation, users end up seeing raw, incomprehensible RSC data rather than a functional UI in html.
Expected behavior:
✅ The page should be rendered as a normal HTML document.
Actual behavior:
❌ The browser caches and serves an RSC response instead of HTML.
