-
Notifications
You must be signed in to change notification settings - Fork 29k
Description
Link to the code that reproduces this issue
https://codesandbox.io/p/devbox/modern-violet-m4ptx3?workspaceId=ws_WttkrM2Pr33FxG8UFgh8Lc
To Reproduce
- Export a static Next.js site with
output: 'export'
set in next.config.js. - Host the output (out/) folder using a generic static HTTP server that serves .txt files without Content-Type.
- Navigate to the site and inspect prefetch behavior for components pointing to static pages.
- Observe that while the page should be rendered in place, clicking the link results in a full page reload.
- In devtools, observe that the browser does fetch the correct .txt file (e.g., index.txt).
A live demo: https://next-prefetch-test.mountainaire.workers.dev/
Current vs. Expected behavior
Expected:
When prefetching a static page, Next.js should recognize the .txt response and perform client-side navigation if needed, as long as the content is correct and the file exists.
Observed:
If the HTTP server serves .txt files without header Content-Type: text/plain
, Next.js fails this check and falls back to a full page navigation:
next.js/packages/next/src/client/components/router-reducer/fetch-server-response.ts
Lines 184 to 203 in 30a7204
let isFlightResponse = contentType.startsWith(RSC_CONTENT_TYPE_HEADER) | |
if (process.env.NODE_ENV === 'production') { | |
if (process.env.__NEXT_CONFIG_OUTPUT === 'export') { | |
if (!isFlightResponse) { | |
isFlightResponse = contentType.startsWith('text/plain') | |
} | |
} | |
} | |
// If fetch returns something different than flight response handle it like a mpa navigation | |
// If the fetch was not 200, we also handle it like a mpa navigation | |
if (!isFlightResponse || !res.ok || !res.body) { | |
// in case the original URL came with a hash, preserve it before redirecting to the new URL | |
if (url.hash) { | |
responseUrl.hash = url.hash | |
} | |
return doMpaNavigation(responseUrl.toString()) | |
} |
Provide environment information
Next.js config:
{
output: 'export'
}
Which area(s) are affected? (Select all that apply)
Route Handlers
Which stage(s) are affected? (Select all that apply)
Other (Deployed)
Additional context
This issue happens when deploying a statically exported site to a somewhat strange static server that does not report the correct MIME type for .txt files in the response header. Because of how the Next.js router checks the Content-Type, even successful fetches of the .txt files are treated as invalid, resulting in broken prefetching and full page reloads.
Possible solution:
Loosening the check for valid prefetch responses to not rely on Content-Type: text/plain
.