Skip to content

Commit 08ee5f6

Browse files
authored
Fix dynamicParams false layout case in dev (#81990)
This ensures we don't consider a path as ISR in development when it will be dynamic during a build due to no `generateStaticParams` being fully generated for a path. Fixes: #81976 Closes: NEXT-4650
1 parent d5f6c11 commit 08ee5f6

File tree

8 files changed

+148
-17
lines changed

8 files changed

+148
-17
lines changed

packages/next/src/build/templates/app-page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ export async function handler(
12401240
}
12411241
} catch (err) {
12421242
// if we aren't wrapped by base-server handle here
1243-
if (!activeSpan) {
1243+
if (!activeSpan && !(err instanceof NoFallbackError)) {
12441244
await routeModule.onRequestError(
12451245
req,
12461246
err,

packages/next/src/build/templates/app-route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ export async function handler(
449449
}
450450
} catch (err) {
451451
// if we aren't wrapped by base-server handle here
452-
if (!activeSpan) {
452+
if (!activeSpan && !(err instanceof NoFallbackError)) {
453453
await routeModule.onRequestError(req, err, {
454454
routerKind: 'App Router',
455455
routePath: normalizedSrcPage,

packages/next/src/server/dev/next-dev-server.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,12 @@ export default class DevServer extends Server {
894894
fallbackMode: fallback,
895895
}
896896

897-
if (res.value?.fallbackMode !== undefined) {
897+
if (
898+
res.value?.fallbackMode !== undefined &&
899+
// This matches the hasGenerateStaticParams logic
900+
// we do during build
901+
(!isAppPath || (staticPaths && staticPaths.length > 0))
902+
) {
898903
// we write the static paths to partial manifest for
899904
// fallback handling inside of entry handler's
900905
const rawExistingManifest = await fs.promises.readFile(

packages/next/src/server/route-modules/pages/pages-handler.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -745,20 +745,22 @@ export const getHandler = ({
745745
)
746746
}
747747
} catch (err) {
748-
await routeModule.onRequestError(
749-
req,
750-
err,
751-
{
752-
routerKind: 'Pages Router',
753-
routePath: srcPage,
754-
routeType: 'render',
755-
revalidateReason: getRevalidateReason({
756-
isRevalidate: hasStaticProps,
757-
isOnDemandRevalidate,
758-
}),
759-
},
760-
routerServerContext
761-
)
748+
if (!(err instanceof NoFallbackError)) {
749+
await routeModule.onRequestError(
750+
req,
751+
err,
752+
{
753+
routerKind: 'Pages Router',
754+
routePath: srcPage,
755+
routeType: 'render',
756+
revalidateReason: getRevalidateReason({
757+
isRevalidate: hasStaticProps,
758+
isOnDemandRevalidate,
759+
}),
760+
},
761+
routerServerContext
762+
)
763+
}
762764

763765
// rethrow so that we can handle serving error page
764766
throw err

test/e2e/app-dir/app-static/app-static.test.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ describe('app-dir static/dynamic handling', () => {
4040
}
4141
})
4242

43+
if (!process.env.__NEXT_EXPERIMENTAL_PPR) {
44+
it('should respond correctly for dynamic route with dynamicParams false in layout', async () => {
45+
const res = await next.fetch('/partial-params-false/en/another')
46+
expect(res.status).toBe(200)
47+
})
48+
49+
it('should respond correctly for partially dynamic route with dynamicParams false in layout', async () => {
50+
const res = await next.fetch('/partial-params-false/en/static')
51+
expect(res.status).toBe(200)
52+
})
53+
}
54+
4355
it('should use auto no cache when no fetch config', async () => {
4456
const res = await next.fetch('/no-config-fetch')
4557
expect(res.status).toBe(200)
@@ -877,6 +889,10 @@ describe('app-dir static/dynamic handling', () => {
877889
"partial-gen-params-no-additional-slug/fr/first.rsc",
878890
"partial-gen-params-no-additional-slug/fr/second.html",
879891
"partial-gen-params-no-additional-slug/fr/second.rsc",
892+
"partial-params-false/en/static.html",
893+
"partial-params-false/en/static.rsc",
894+
"partial-params-false/fr/static.html",
895+
"partial-params-false/fr/static.rsc",
880896
"prerendered-not-found/first.html",
881897
"prerendered-not-found/first.rsc",
882898
"prerendered-not-found/second.html",
@@ -1822,6 +1838,54 @@ describe('app-dir static/dynamic handling', () => {
18221838
"initialRevalidateSeconds": false,
18231839
"srcRoute": "/partial-gen-params-no-additional-slug/[lang]/[slug]",
18241840
},
1841+
"/partial-params-false/en/static": {
1842+
"allowHeader": [
1843+
"host",
1844+
"x-matched-path",
1845+
"x-prerender-revalidate",
1846+
"x-prerender-revalidate-if-generated",
1847+
"x-next-revalidated-tags",
1848+
"x-next-revalidate-tag-token",
1849+
],
1850+
"dataRoute": "/partial-params-false/en/static.rsc",
1851+
"experimentalBypassFor": [
1852+
{
1853+
"key": "Next-Action",
1854+
"type": "header",
1855+
},
1856+
{
1857+
"key": "content-type",
1858+
"type": "header",
1859+
"value": "multipart/form-data;.*",
1860+
},
1861+
],
1862+
"initialRevalidateSeconds": false,
1863+
"srcRoute": "/partial-params-false/[locale]/static",
1864+
},
1865+
"/partial-params-false/fr/static": {
1866+
"allowHeader": [
1867+
"host",
1868+
"x-matched-path",
1869+
"x-prerender-revalidate",
1870+
"x-prerender-revalidate-if-generated",
1871+
"x-next-revalidated-tags",
1872+
"x-next-revalidate-tag-token",
1873+
],
1874+
"dataRoute": "/partial-params-false/fr/static.rsc",
1875+
"experimentalBypassFor": [
1876+
{
1877+
"key": "Next-Action",
1878+
"type": "header",
1879+
},
1880+
{
1881+
"key": "content-type",
1882+
"type": "header",
1883+
"value": "multipart/form-data;.*",
1884+
},
1885+
],
1886+
"initialRevalidateSeconds": false,
1887+
"srcRoute": "/partial-params-false/[locale]/static",
1888+
},
18251889
"/prerendered-not-found/first": {
18261890
"allowHeader": [
18271891
"host",
@@ -2580,6 +2644,31 @@ describe('app-dir static/dynamic handling', () => {
25802644
"fallback": false,
25812645
"routeRegex": "^\\/partial\\-gen\\-params\\-no\\-additional\\-slug\\/([^\\/]+?)\\/([^\\/]+?)(?:\\/)?$",
25822646
},
2647+
"/partial-params-false/[locale]/static": {
2648+
"allowHeader": [
2649+
"host",
2650+
"x-matched-path",
2651+
"x-prerender-revalidate",
2652+
"x-prerender-revalidate-if-generated",
2653+
"x-next-revalidated-tags",
2654+
"x-next-revalidate-tag-token",
2655+
],
2656+
"dataRoute": "/partial-params-false/[locale]/static.rsc",
2657+
"dataRouteRegex": "^\\/partial\\-params\\-false\\/([^\\/]+?)\\/static\\.rsc$",
2658+
"experimentalBypassFor": [
2659+
{
2660+
"key": "Next-Action",
2661+
"type": "header",
2662+
},
2663+
{
2664+
"key": "content-type",
2665+
"type": "header",
2666+
"value": "multipart/form-data;.*",
2667+
},
2668+
],
2669+
"fallback": false,
2670+
"routeRegex": "^\\/partial\\-params\\-false\\/([^\\/]+?)\\/static(?:\\/)?$",
2671+
},
25832672
"/prerendered-not-found/[slug]": {
25842673
"allowHeader": [
25852674
"host",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export default async function Page({ params }) {
2+
const { locale, slug } = await params
3+
4+
return (
5+
<>
6+
<p>/[locale]/[slug]/page</p>
7+
<p>params: {JSON.stringify({ locale, slug })}</p>
8+
</>
9+
)
10+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export const dynamicParams = false
2+
3+
export function generateStaticParams() {
4+
return [
5+
{
6+
locale: 'en',
7+
},
8+
{
9+
locale: 'fr',
10+
},
11+
]
12+
}
13+
14+
export default function Layout({ children }) {
15+
return <>{children}</>
16+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default async function Page({ params }) {
2+
const { locale } = await params
3+
return (
4+
<>
5+
<p>/[locale]/static</p>
6+
<p>locale: {locale}</p>
7+
</>
8+
)
9+
}

0 commit comments

Comments
 (0)