Skip to content

Commit e9ef3b8

Browse files
authored
feat(next): improve fallback root params handling with hasFallbackRootParams flag (#13653)
## Summary This PR improves the handling of fallback root parameters by introducing a `hasFallbackRootParams` flag to simplify route regex generation and enhance prerender manifest processing. ## Changes - Add `hasFallbackRootParams` flag to `RoutesManifestRoute` type for better type safety - Simplify route regex generation when `hasFallbackRootParams` is true by using a more direct `.rsc` suffix - Update prerender manifest handling for both fallback and blocking fallback routes - Improve conditional logic for fallback root params processing in the prerender route handler ## Test plan - [ ] Verify existing tests pass - [ ] Test route generation with and without fallback root params - [ ] Validate prerender manifest structure includes new fields Related Pull Request: vercel/next.js#82282
1 parent a78f91c commit e9ef3b8

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@vercel/next': minor
3+
---
4+
5+
Improve fallback root params handling with hasFallbackRootParams flag
6+
7+
- Add hasFallbackRootParams flag to RoutesManifestRoute type for simplified route regex generation
8+
- Update route handling logic to conditionally apply fallback root params processing
9+
- Enhance prerender manifest structure with fallback root params support

packages/next/src/utils.ts

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,18 @@ type RoutesManifestRoute = {
224224
regex: string;
225225
namedRegex?: string;
226226
routeKeys?: { [named: string]: string };
227+
228+
/**
229+
* If true, this indicates that the route has fallback root params. This is
230+
* used to simplify the route regex for matching.
231+
*/
232+
hasFallbackRootParams?: boolean;
233+
234+
/**
235+
* The prefetch segment data routes for this route. This is used to rewrite
236+
* the prefetch segment data routes (or the inverse) to the correct
237+
* destination.
238+
*/
227239
prefetchSegmentDataRoutes?: {
228240
source: string;
229241
destination: string;
@@ -473,6 +485,7 @@ export async function getDynamicRoutes({
473485
regex,
474486
routeKeys,
475487
prefetchSegmentDataRoutes,
488+
hasFallbackRootParams,
476489
} = params;
477490
const route: RouteWithSrc = {
478491
src: namedRegex || regex,
@@ -540,9 +553,14 @@ export async function getDynamicRoutes({
540553
routes.push({
541554
src: route.src.replace(
542555
new RegExp(escapeStringRegexp('(?:/)?$')),
543-
'(?<rscSuffix>\\.rsc|\\.prefetch\\.rsc|\\.segments/.+\\.segment\\.rsc)(?:/)?$'
556+
hasFallbackRootParams
557+
? '\\.rsc(?:/)?$'
558+
: '(?<rscSuffix>\\.rsc|\\.prefetch\\.rsc|\\.segments/.+\\.segment\\.rsc)(?:/)?$'
559+
),
560+
dest: route.dest?.replace(
561+
/($|\?)/,
562+
hasFallbackRootParams ? '.rsc$1' : '$rscSuffix$1'
544563
),
545-
dest: route.dest?.replace(/($|\?)/, '$rscSuffix$1'),
546564
check: true,
547565
override: true,
548566
});
@@ -1078,6 +1096,7 @@ export type NextPrerenderedRoutes = {
10781096
[route: string]: {
10791097
routeRegex: string;
10801098
dataRoute: string | null;
1099+
fallback: string | boolean | null;
10811100
fallbackRootParams?: string[];
10821101
dataRouteRegex: string | null;
10831102
prefetchDataRoute?: string | null;
@@ -1285,6 +1304,7 @@ export async function getPrerenderManifest(
12851304
dynamicRoutes: {
12861305
[key: string]: {
12871306
fallback?: string;
1307+
fallbackRootParams?: string[];
12881308
routeRegex: string;
12891309
dataRoute: string;
12901310
dataRouteRegex: string;
@@ -1391,8 +1411,13 @@ export async function getPrerenderManifest(
13911411
});
13921412

13931413
lazyRoutes.forEach(lazyRoute => {
1394-
const { routeRegex, fallback, dataRoute, dataRouteRegex } =
1395-
manifest.dynamicRoutes[lazyRoute];
1414+
const {
1415+
routeRegex,
1416+
fallback,
1417+
dataRoute,
1418+
dataRouteRegex,
1419+
fallbackRootParams,
1420+
} = manifest.dynamicRoutes[lazyRoute];
13961421

13971422
if (fallback) {
13981423
ret.fallbackRoutes[lazyRoute] = {
@@ -1407,6 +1432,8 @@ export async function getPrerenderManifest(
14071432
ret.blockingFallbackRoutes[lazyRoute] = {
14081433
routeRegex,
14091434
dataRoute,
1435+
fallback: null,
1436+
fallbackRootParams,
14101437
dataRouteRegex,
14111438
renderingMode: RenderingMode.STATIC,
14121439
allowHeader: undefined,
@@ -1551,6 +1578,7 @@ export async function getPrerenderManifest(
15511578
renderingMode,
15521579
allowHeader,
15531580
fallbackRootParams,
1581+
fallback: null,
15541582
};
15551583
} else {
15561584
ret.omittedRoutes[lazyRoute] = {
@@ -2789,11 +2817,16 @@ export const onPrerenderRoute =
27892817
renderingMode === RenderingMode.PARTIALLY_STATIC &&
27902818
(isFallback || isBlocking)
27912819
) {
2792-
const { fallbackRootParams } = isFallback
2820+
const { fallbackRootParams, fallback } = isFallback
27932821
? prerenderManifest.fallbackRoutes[routeKey]
27942822
: prerenderManifest.blockingFallbackRoutes[routeKey];
27952823

2796-
if (fallbackRootParams && fallbackRootParams.length > 0) {
2824+
if (
2825+
fallback &&
2826+
typeof fallback === 'string' &&
2827+
fallbackRootParams &&
2828+
fallbackRootParams.length > 0
2829+
) {
27972830
htmlAllowQuery = fallbackRootParams;
27982831
} else if (postponedPrerender) {
27992832
htmlAllowQuery = [];

0 commit comments

Comments
 (0)