Files
Andrew ClarkandGitHub 3717cd3dfb Gate partial fallback shell upgrades behind partialPrefetching for next start (#96297)
In #96074 I put the `partialFallback` behavior behind the
`partialPrefetching` flag, so that we don't risk an explosion in ISR
costs for apps that haven't opted into Partial Prefetching. But it turns
out I only handled this for deploy mode — i.e. the build output consumed
by the Vercel adapter. The behavior was still unconditionally on for
`next start`.

The reason it was easy to miss is that `next start` and the adapter
express partial fallback shells through completely separate mechanisms.
The adapter emits a `partialFallback` flag into the build output and
lets the platform's ISR layer perform the shell upgrade. `next start`
has no such flag; the server performs the upgrade itself, in the
compiled page runtime. So the gate I added to the adapter output had no
effect on the self-hosted path.

To understand how the `next start` path was configured, I looked at the
PR that removed the original top-level `partialFallbacks` config flag
(#93859). Before that PR, the behavior was gated in the runtime; when
the flag was removed those gates were deleted and the behavior became
always-on.

The important subtlety is that only the *upgrade* should be gated, not
the shell machinery as a whole. On `next start`, the value that decides
whether a shell can be specialized (`remainingPrerenderableParams`) also
drives core Cache Components behavior — build-time partial prerendering
of params and serving build-time sub-shells — which must stay on
regardless of `partialPrefetching`. So this gates only the two things
that make up the "upgrade on first request" cost risk: the background
ISR revalidation that specializes a shell per request, and the
client-facing `isFallbackUpgradeable` signal that tells the client to
retry a prefetch waiting for that upgrade.

Adds coverage with a `partialPrefetching`-disabled fixture asserting
that fallback shells stay shared rather than specializing per request.
2026-07-29 19:56:49 +00:00

40 lines
1.1 KiB
JavaScript

/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
// The Cache Components cases in this suite (run with __NEXT_CACHE_COMPONENTS)
// exercise the navigation-triggered upgrade of a fallback shell into a
// concrete route shell, which only runs when Partial Prefetching is enabled.
// Enable it only in that mode: `partialPrefetching` requires Cache Components,
// so setting it unconditionally would fail the build in the non-Cache
// Components mode this fixture also runs in.
partialPrefetching: process.env.__NEXT_CACHE_COMPONENTS === 'true',
experimental: {
prefetchInlining: false,
useCache: true,
},
rewrites: async () => {
return {
beforeFiles: [
{
source: '/:first/~/overview/:path*',
destination: '/404',
},
{
source: '/:first',
has: [
{
type: 'cookie',
key: 'overview-param',
value: 'grid',
},
],
destination: '/:first/~/overview/grid',
},
],
}
},
}
module.exports = nextConfig