Skip to content

Commit f46be95

Browse files
committed
fix: correctly handle prerendered dynamic RSC routes
1 parent 2a02c87 commit f46be95

File tree

2 files changed

+30
-22
lines changed

2 files changed

+30
-22
lines changed

packages/runtime/src/helpers/edge.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import type { NetlifyConfig, NetlifyPluginConstants } from '@netlify/build'
55
import { greenBright } from 'chalk'
66
import destr from 'destr'
77
import { copy, copyFile, emptyDir, ensureDir, readJSON, readJson, writeJSON, writeJson } from 'fs-extra'
8-
import type { PrerenderManifest, SsgRoute } from 'next/dist/build'
8+
import type { PrerenderManifest } from 'next/dist/build'
99
import type { MiddlewareManifest } from 'next/dist/build/webpack/plugins/middleware-plugin'
1010
import type { RouteHas } from 'next/dist/lib/load-custom-routes'
1111
import { outdent } from 'outdent'
1212

1313
import { getRequiredServerFiles, NextConfig } from './config'
1414
import { makeLocaleOptional, stripLookahead } from './matchers'
15-
import { DynamicRoute, RoutesManifest } from './types'
15+
import { RoutesManifest } from './types'
1616

1717
// This is the format as of next@12.2
1818
interface EdgeFunctionDefinitionV1 {
@@ -70,14 +70,8 @@ const maybeLoadJson = <T>(path: string): Promise<T> | null => {
7070
return readJson(path)
7171
}
7272
}
73-
74-
export const isStaticAppDirRoute = ({ srcRoute }: SsgRoute, manifest: Record<string, string> | null): boolean =>
75-
Boolean(manifest) && Object.values(manifest).includes(srcRoute)
76-
77-
export const isDynamicAppDirRoute = (
78-
{ page }: Pick<DynamicRoute, 'page'>,
79-
manifest: Record<string, string> | null,
80-
): boolean => Boolean(manifest) && Object.values(manifest).includes(page)
73+
export const isAppDirRoute = (route: string, appPathRoutesManifest: Record<string, string> | null): boolean =>
74+
Boolean(appPathRoutesManifest) && Object.values(appPathRoutesManifest).includes(route)
8175

8276
export const loadMiddlewareManifest = (netlifyConfig: NetlifyConfig): Promise<MiddlewareManifest | null> =>
8377
maybeLoadJson(resolve(netlifyConfig.build.publish, 'server', 'middleware-manifest.json'))
@@ -320,23 +314,38 @@ export const writeRscDataEdgeFunction = async ({
320314
}
321315
const staticAppdirRoutes: Array<string> = []
322316
for (const [path, route] of Object.entries(prerenderManifest.routes)) {
323-
if (isStaticAppDirRoute(route, appPathRoutesManifest)) {
317+
if (isAppDirRoute(route.srcRoute, appPathRoutesManifest)) {
324318
staticAppdirRoutes.push(path, route.dataRoute)
325319
}
326320
}
327-
if (staticAppdirRoutes.length === 0) {
321+
const dynamicAppDirRoutes: Array<string> = []
322+
323+
for (const [path, route] of Object.entries(prerenderManifest.dynamicRoutes)) {
324+
if (isAppDirRoute(path, appPathRoutesManifest)) {
325+
dynamicAppDirRoutes.push(route.routeRegex, route.dataRouteRegex)
326+
}
327+
}
328+
329+
if (staticAppdirRoutes.length === 0 && dynamicAppDirRoutes.length === 0) {
328330
return []
329331
}
330332

331333
const edgeFunctionDir = resolve('.netlify', 'edge-functions', 'rsc-data')
332334
await ensureDir(edgeFunctionDir)
333335
await copyEdgeSourceFile({ edgeFunctionDir, file: 'rsc-data.ts' })
334336

335-
return staticAppdirRoutes.map((path) => ({
336-
function: 'rsc-data',
337-
name: 'RSC data routing',
338-
path,
339-
}))
337+
return [
338+
...staticAppdirRoutes.map((path) => ({
339+
function: 'rsc-data',
340+
name: 'RSC data routing',
341+
path,
342+
})),
343+
...dynamicAppDirRoutes.map((pattern) => ({
344+
function: 'rsc-data',
345+
name: 'RSC data routing',
346+
pattern,
347+
})),
348+
]
340349
}
341350

342351
/**

packages/runtime/src/helpers/redirects.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { join } from 'pathe'
88

99
import { HANDLER_FUNCTION_PATH, HIDDEN_PATHS, ODB_FUNCTION_PATH } from '../constants'
1010

11-
import { isDynamicAppDirRoute, isStaticAppDirRoute, loadAppPathRoutesManifest } from './edge'
11+
import { isAppDirRoute, loadAppPathRoutesManifest } from './edge'
1212
import { getMiddleware } from './files'
1313
import { ApiRouteConfig } from './functions'
1414
import { RoutesManifest } from './types'
@@ -135,8 +135,7 @@ const generateStaticIsrRewrites = ({
135135
const staticIsrRoutesThatMatchMiddleware: Array<string> = []
136136
const staticRoutePaths = new Set<string>()
137137
const staticIsrRewrites: NetlifyConfig['redirects'] = []
138-
staticRouteEntries.forEach(([route, ssgRoute]) => {
139-
const { initialRevalidateSeconds, dataRoute } = ssgRoute
138+
staticRouteEntries.forEach(([route, { initialRevalidateSeconds, dataRoute, srcRoute }]) => {
140139
if (isApiRoute(route) || is404Route(route, i18n)) {
141140
return
142141
}
@@ -147,7 +146,7 @@ const generateStaticIsrRewrites = ({
147146
return
148147
}
149148
// appDir routes are a different format, so we need to handle them differently
150-
const isAppDir = isStaticAppDirRoute(ssgRoute, appPathRoutes)
149+
const isAppDir = isAppDirRoute(srcRoute, appPathRoutes)
151150
// The default locale is served from the root, not the localised path
152151
if (i18n?.defaultLocale && route.startsWith(`/${i18n.defaultLocale}/`)) {
153152
route = route.slice(i18n.defaultLocale.length + 1)
@@ -227,7 +226,7 @@ const generateDynamicRewrites = ({
227226
if (route.page in prerenderedDynamicRoutes) {
228227
if (matchesMiddleware(middleware, route.page)) {
229228
dynamicRoutesThatMatchMiddleware.push(route.page)
230-
} else if (isDynamicAppDirRoute(route, appPathRoutes)) {
229+
} else if (isAppDirRoute(route.page, appPathRoutes)) {
231230
dynamicRewrites.push(
232231
...redirectsForNextRoute({
233232
route: route.page,

0 commit comments

Comments
 (0)