Skip to content

(2/19) Emit export dynamic fallback RSC artifacts#93558

Draft
feedthejim wants to merge 1 commit intofeedthejim/export-dynamic-fallback-build-htmlfrom
feedthejim/export-dynamic-fallback-build-rsc
Draft

(2/19) Emit export dynamic fallback RSC artifacts#93558
feedthejim wants to merge 1 commit intofeedthejim/export-dynamic-fallback-build-htmlfrom
feedthejim/export-dynamic-fallback-build-rsc

Conversation

@feedthejim
Copy link
Copy Markdown
Contributor

@feedthejim feedthejim commented May 7, 2026

Stack position

Part 2 of 19 in the output export dynamic fallback stack.

Previous PR: #93557 (1/19)
Next PR: #93560 (3/19)

Context

The stack is split so build-time output can land behind experimental.outputExportDynamicFallbacks before the client router behavior is enabled. The target behavior is for output: 'export' apps with parameterized App Router routes to emit fallback HTML/RSC artifacts that a later client can resolve for hard loads and soft navigations.

This PR scope: Build-time fallback RSC artifacts for route segments.

Once fallback HTML can exist, the client also needs static RSC payloads to resolve parameterized routes. This PR is still build-only: it writes the fallback data that a later client can fetch.

What changed

  • Generates fallback RSC files for dynamic route directories using the loader tree.
  • Preserves static export naming for both flat and trailing-slash output.
  • Keeps the output behind the same experimental flag.

Deliberately not included

  • Does not teach the client router to discover these files.
  • Does not handle conflicting dynamic route shapes yet.
  • Does not change runtime behavior when the flag is off.

Verification

After restacking and autosquashing, I verified the full stack with:

  • pnpm --filter=next build
  • pnpm testonly packages/next/src/lib/output-export-dynamic-fallback.test.ts packages/next/src/lib/output-export-fallback-routes.test.ts packages/next/src/export/helpers/output-export-fallback.test.ts packages/next/src/server/request/fallback-params.test.ts
  • pnpm testonly packages/next/src/client/output-export-fallback.test.ts packages/next/src/client/components/router-reducer/fetch-server-response.test.ts packages/next/src/client/components/router-reducer/create-initial-router-state.test.ts packages/next/src/client/components/segment-cache/cache.test.ts packages/next/src/client/components/segment-cache/vary-path.test.ts
  • pnpm testonly packages/next/src/client/components/router-reducer/compute-changed-path.test.ts packages/next/src/client/flight-data-helpers.test.ts packages/next/src/server/app-render/postponed-state.test.ts
  • pnpm test-start-turbo test/e2e/app-dir-export/test/dynamic-fallback-cache-components.test.ts test/e2e/app-dir-export/test/dynamic-fallback-route-shapes-cache-components.test.ts test/e2e/app-dir-export/test/dynamic-fallback-cache-components-basepath.test.ts test/e2e/app-dir-export/test/dynamic-fallback-optimizations-cache-components.test.ts test/e2e/app-dir-export/test/dynamic-fallback-known-params-cache-components.test.ts test/e2e/app-dir-export/test/dynamic-fallback-conflict.test.ts
  • pnpm test-start-turbo test/e2e/app-dir/output-export-dynamic-fallbacks/output-export-dynamic-fallbacks.test.ts test/e2e/app-dir-export/test/output-export-server-io.test.ts test/e2e/app-dir-export/test/output-export-server-io-use-cache.test.ts test/e2e/app-dir-export/test/dynamic-fallback-server-params.test.ts

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Tests Passed

Commit: 024a7c9

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Stats from current PR

🔴 1 regression

Metric Canary PR Change Trend
node_modules Size 505 MB 505 MB 🔴 +110 kB (+0%) ▁▁▁▁█
📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 811ms 812ms ▁████
Cold (Ready in log) 773ms 771ms ▁▇███
Cold (First Request) 1.204s 1.184s ▁▇▆▇▆
Warm (Listen) 811ms 811ms ▁████
Warm (Ready in log) 772ms 773ms ▁█▇██
Warm (First Request) 571ms 574ms ▁▇▆█▇
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 812ms 810ms ▁████
Cold (Ready in log) 786ms 787ms ▁▇█▆▆
Cold (First Request) 3.165s 3.187s ▁▅▆▂▃
Warm (Listen) 810ms 810ms ▁████
Warm (Ready in log) 786ms 787ms ▁▇█▆▆
Warm (First Request) 3.156s 3.166s ▁█▇▃▄

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 4.681s 4.687s ▆█▂▆▇
Cached Build 4.705s 4.713s ▆▇▂▇█
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 23.738s 23.808s ▁▅▄▃▃
Cached Build 23.899s 23.870s ▁▆▆▄▄
node_modules Size 505 MB 505 MB 🔴 +110 kB (+0%) ▁▁▁▁█
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles
Canary PR Change
0-uzeva3n66k2.js gzip 167 B N/A -
04hm05ar7kldw.js gzip 5.73 kB N/A -
0cz1d0mv5g_q7.js gzip 39.4 kB 39.4 kB
0j4jd3451671q.js gzip 153 B N/A -
0m_5ws7ey529t.js gzip 153 B N/A -
0q_zozu0nq_np.js gzip 8.51 kB N/A -
0t5pto9nz_a46.js gzip 157 B N/A -
11k871bhqlh_5.js gzip 153 B N/A -
13lrt22t_69qa.js gzip 8.6 kB N/A -
13s20nrhn4s8-.js gzip 13.8 kB N/A -
1elt1qium-r2m.css gzip 115 B 115 B
1gl3a__5l_dtd.js gzip 156 B N/A -
1jpaub6y8xlfr.js gzip 2.3 kB N/A -
1ndiq9qwifl1p.js gzip 70.8 kB N/A -
1ot0mvscrc_uf.js gzip 233 B N/A -
1uqyjms2v3a2x.js gzip 10.4 kB N/A -
1uvgljrndpyc4.js gzip 153 B N/A -
1v0ycni370q_7.js gzip 8.52 kB N/A -
1y6koqf4yz3ro.js gzip 160 B N/A -
2_m3xv2uq3sjc.js gzip 1.46 kB N/A -
2extn3odmmem_.js gzip 12.9 kB N/A -
2fyhyy7niw9r6.js gzip 7.61 kB N/A -
2n4_qu-uljlk3.js gzip 152 B N/A -
2riibg1ndirpj.js gzip 10.1 kB N/A -
2rxsvztg69t2h.js gzip 154 B N/A -
2zc4tax40sui6.js gzip 9.24 kB N/A -
30r8mm-46bdqy.js gzip 220 B 220 B
30syle__9u-ms.js gzip 65.5 kB N/A -
32edp808ols1d.js gzip 159 B N/A -
3dd42mxmevz1t.js gzip 49.5 kB N/A -
3dnxhpk39f53v.js gzip 8.57 kB N/A -
3dsng975is7ps.js gzip 8.59 kB N/A -
3inab2jybr4k9.js gzip 450 B N/A -
3jkm5tdjvaf_q.js gzip 13.1 kB N/A -
3jvw4u1y018lt.js gzip 9.82 kB N/A -
3kfxy6omiyi8i.js gzip 8.57 kB N/A -
3lnpwxi48bs2r.js gzip 154 B N/A -
3r9qhujmuwkzb.js gzip 8.63 kB N/A -
3rna-uxopfrvd.js gzip 8.6 kB N/A -
3s6cjuc9cll-v.js gzip 155 B N/A -
3tndwlmduss27.js gzip 13.4 kB N/A -
turbopack-0j..tpsn.js gzip 4.2 kB N/A -
turbopack-0m..48uk.js gzip 4.19 kB N/A -
turbopack-0o..il9_.js gzip 4.19 kB N/A -
turbopack-1_..6t5n.js gzip 4.2 kB N/A -
turbopack-19..gxwk.js gzip 4.2 kB N/A -
turbopack-19..bkiz.js gzip 4.2 kB N/A -
turbopack-1h..6fog.js gzip 4.2 kB N/A -
turbopack-1z..ssuk.js gzip 4.2 kB N/A -
turbopack-23..8bxm.js gzip 4.2 kB N/A -
turbopack-2b..omkf.js gzip 4.2 kB N/A -
turbopack-2h..r2fo.js gzip 4.21 kB N/A -
turbopack-2t..qk2n.js gzip 4.18 kB N/A -
turbopack-30..xc6f.js gzip 4.2 kB N/A -
turbopack-37..yln9.js gzip 4.2 kB N/A -
03_5w3jfg2kc-.js gzip N/A 10.1 kB -
05e40c15cx1dd.js gzip N/A 7.61 kB -
05pe8rzbupg6u.js gzip N/A 10.4 kB -
05v6t_jh5f_yx.js gzip N/A 13.8 kB -
0806zgk7siyp7.js gzip N/A 8.6 kB -
08dxtljl67uwg.js gzip N/A 156 B -
0fod6nyyd77zu.js gzip N/A 49.5 kB -
0htsbiobnao9x.js gzip N/A 13.4 kB -
0m34gln_kt4fg.js gzip N/A 5.73 kB -
0rs6tf8z8po60.js gzip N/A 8.52 kB -
16f2cu5irq6cm.js gzip N/A 160 B -
1an3yhxaoku_n.js gzip N/A 155 B -
1av1jag822n6l.js gzip N/A 8.51 kB -
1er7dqnoopydf.js gzip N/A 8.59 kB -
1g3q1ww01thnl.js gzip N/A 2.3 kB -
1i0eqvqjhhe_v.js gzip N/A 8.57 kB -
1i2188wh2oorx.js gzip N/A 157 B -
1l9un1sl77287.js gzip N/A 1.46 kB -
1plr452d5ya0m.js gzip N/A 155 B -
1q98wrj3--vyg.js gzip N/A 155 B -
1rpz5kbg-qi7x.js gzip N/A 170 B -
1z4y3zbj8nguh.js gzip N/A 70.8 kB -
2147zgtf14z-q.js gzip N/A 234 B -
23ro2xkthrr36.js gzip N/A 156 B -
25z5pyx03noy-.js gzip N/A 8.57 kB -
2lf717n7y9xvn.js gzip N/A 9.82 kB -
2st_qs6p_9us0.js gzip N/A 13.1 kB -
3214a3_0hs02x.js gzip N/A 8.6 kB -
353cu5e7jhyu_.js gzip N/A 157 B -
35805fay7jtzc.js gzip N/A 65.6 kB -
38l-2n-xv_j.js gzip N/A 9.24 kB -
3ei-smgdrgxyw.js gzip N/A 156 B -
3hqti_t-zy1x4.js gzip N/A 449 B -
3nser88va0i70.js gzip N/A 161 B -
3pvkpa748u31-.js gzip N/A 157 B -
3qov6fn4ke7dt.js gzip N/A 152 B -
3z3a37i3a_vgl.js gzip N/A 8.63 kB -
41mf-x3mmsxae.js gzip N/A 12.9 kB -
turbopack-0q..w8sw.js gzip N/A 4.2 kB -
turbopack-0y..gef9.js gzip N/A 4.2 kB -
turbopack-1o..u_k4.js gzip N/A 4.2 kB -
turbopack-1q..hm8b.js gzip N/A 4.2 kB -
turbopack-26..wic1.js gzip N/A 4.2 kB -
turbopack-28..z8dg.js gzip N/A 4.21 kB -
turbopack-2b..pe_l.js gzip N/A 4.2 kB -
turbopack-2e..2st1.js gzip N/A 4.2 kB -
turbopack-2j..3920.js gzip N/A 4.2 kB -
turbopack-2j..l1ht.js gzip N/A 4.18 kB -
turbopack-2l..1iot.js gzip N/A 4.2 kB -
turbopack-35..p-rf.js gzip N/A 4.2 kB -
turbopack-3w..wbem.js gzip N/A 4.2 kB -
turbopack-3x..igwd.js gzip N/A 4.2 kB -
Total 466 kB 466 kB ⚠️ +101 B

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 717 B 718 B
Total 717 B 718 B ⚠️ +1 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 431 B 434 B
Total 431 B 434 B ⚠️ +3 B

📦 Webpack

Client

Main Bundles
Canary PR Change
2258-HASH.js gzip 61.1 kB N/A -
2266-HASH.js gzip 4.69 kB N/A -
3317.HASH.js gzip 169 B N/A -
4866-HASH.js gzip 5.64 kB N/A -
9e302639-HASH.js gzip 62.7 kB N/A -
framework-HASH.js gzip 59.5 kB 59.5 kB
main-app-HASH.js gzip 256 B 255 B
main-HASH.js gzip 39.7 kB 39.7 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
175fd0fd-HASH.js gzip N/A 62.7 kB -
2596-HASH.js gzip N/A 5.63 kB -
34-HASH.js gzip N/A 61 kB -
5691.HASH.js gzip N/A 169 B -
9156-HASH.js gzip N/A 4.68 kB -
Total 235 kB 235 kB ✅ -89 B
Polyfills
Canary PR Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Total 39.4 kB 39.4 kB
Pages
Canary PR Change
_app-HASH.js gzip 193 B 193 B
_error-HASH.js gzip 181 B 182 B
css-HASH.js gzip 334 B 332 B
dynamic-HASH.js gzip 1.79 kB 1.81 kB
edge-ssr-HASH.js gzip 255 B 255 B
head-HASH.js gzip 351 B 348 B
hooks-HASH.js gzip 385 B 384 B
image-HASH.js gzip 580 B 580 B
index-HASH.js gzip 257 B 259 B
link-HASH.js gzip 2.51 kB 2.52 kB
routerDirect..HASH.js gzip 318 B 319 B
script-HASH.js gzip 387 B 386 B
withRouter-HASH.js gzip 316 B 316 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.97 kB 7.99 kB ⚠️ +19 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 126 kB 126 kB
page.js gzip 275 kB 269 kB 🟢 5.27 kB (-2%)
Total 401 kB 396 kB ✅ -5.38 kB
Middleware
Canary PR Change
middleware-b..fest.js gzip 619 B 617 B
middleware-r..fest.js gzip 155 B 155 B
middleware.js gzip 44.4 kB 44.4 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 46 kB 46 kB ⚠️ +41 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 719 B 717 B
Total 719 B 717 B ✅ -2 B
Build Cache
Canary PR Change
0.pack gzip 4.44 MB 4.44 MB 🟢 5.81 kB (0%)
index.pack gzip 113 kB 114 kB
index.pack.old gzip 115 kB 116 kB
Total 4.67 MB 4.67 MB ✅ -4.43 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 349 kB 349 kB
app-page-exp..prod.js gzip 194 kB 194 kB
app-page-tur...dev.js gzip 349 kB 349 kB
app-page-tur..prod.js gzip 194 kB 194 kB
app-page-tur...dev.js gzip 345 kB 345 kB
app-page-tur..prod.js gzip 192 kB 192 kB
app-page.run...dev.js gzip 346 kB 346 kB
app-page.run..prod.js gzip 192 kB 192 kB
app-route-ex...dev.js gzip 77.4 kB 77.4 kB
app-route-ex..prod.js gzip 52.8 kB 52.8 kB
app-route-tu...dev.js gzip 77.4 kB 77.4 kB
app-route-tu..prod.js gzip 52.8 kB 52.8 kB
app-route-tu...dev.js gzip 77 kB 77 kB
app-route-tu..prod.js gzip 52.6 kB 52.6 kB
app-route.ru...dev.js gzip 77 kB 77 kB
app-route.ru..prod.js gzip 52.6 kB 52.6 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 44.3 kB 44.3 kB
pages-api-tu..prod.js gzip 33.7 kB 33.7 kB
pages-api.ru...dev.js gzip 44.3 kB 44.3 kB
pages-api.ru..prod.js gzip 33.7 kB 33.7 kB
pages-turbo....dev.js gzip 53.7 kB 53.7 kB
pages-turbo...prod.js gzip 39.4 kB 39.4 kB
pages.runtim...dev.js gzip 53.7 kB 53.7 kB
pages.runtim..prod.js gzip 39.4 kB 39.4 kB
server.runti..prod.js gzip 63.2 kB 63.2 kB
use-cache-pr...dev.js gzip 69.7 kB 69.7 kB
use-cache-pr...dev.js gzip 69.7 kB 69.7 kB
use-cache-pr...dev.js gzip 68 kB 68 kB
use-cache-pr...dev.js gzip 68 kB 68 kB
Total 3.36 MB 3.36 MB ⚠️ +12 B
📝 Changed Files (5 files)

Files with changes:

  • pages-api-tu..time.prod.js
  • pages-api.ru..time.prod.js
  • pages-turbo...time.prod.js
  • pages.runtime.prod.js
  • server.runtime.prod.js
View diffs
pages-api-tu..time.prod.js

Diff too large to display

pages-api.ru..time.prod.js

Diff too large to display

pages-turbo...time.prod.js

Diff too large to display

pages.runtime.prod.js

Diff too large to display

server.runtime.prod.js

Diff too large to display

📎 Tarball URL
https://vercel-packages.vercel.app/next/commits/acf4f39a80fa32537ae59874881bf55632ef1a4a/next

Commit: acf4f39

@feedthejim feedthejim force-pushed the feedthejim/export-dynamic-fallback-build-rsc branch from 9f2a12b to 6e8f140 Compare May 7, 2026 03:45
@feedthejim feedthejim force-pushed the feedthejim/export-dynamic-fallback-build-html branch from 6b44496 to 4386692 Compare May 7, 2026 03:45
@feedthejim feedthejim changed the title Emit export dynamic fallback RSC artifacts (2/19) Emit export dynamic fallback RSC artifacts May 7, 2026
Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

Inline snapshot in NFT trace test is missing the newly added /node_modules/next/dist/lib/output-export-dynamic-fallback.js entry, causing test failure.

Fix on Vercel

@feedthejim feedthejim force-pushed the feedthejim/export-dynamic-fallback-build-rsc branch from 6e8f140 to acf4f39 Compare May 7, 2026 04:55
@feedthejim feedthejim force-pushed the feedthejim/export-dynamic-fallback-build-html branch from 54401b5 to 29ba2d2 Compare May 7, 2026 13:56
@feedthejim feedthejim force-pushed the feedthejim/export-dynamic-fallback-build-rsc branch from acf4f39 to 09ad584 Compare May 7, 2026 13:56
@feedthejim feedthejim force-pushed the feedthejim/export-dynamic-fallback-build-rsc branch from 09ad584 to 024a7c9 Compare May 7, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant