mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #257] [MERGED] fix(ssr): preload client reference modules before first SSR render #421
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#421
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/cloudflare/vinext/pull/257
Author: @gagipro
Created: 3/5/2026
Status: ✅ Merged
Merged: 3/16/2026
Merged by: @james-elicx
Base:
main← Head:fix/preload-client-refs-ssr📝 Commits (1)
157b13ffix(ssr): preload client reference modules before first SSR render📊 Changes
3 files changed (+122 additions, -0 deletions)
View changed files
📝
packages/vinext/src/entries/app-ssr-entry.ts(+26 -0)📝
tests/__snapshots__/entry-templates.test.ts.snap(+26 -0)📝
tests/app-router.test.ts(+70 -0)📄 Description
Summary
Fixes #256 — the first HTTP request after
vinext startalways returns 500.Problem
On cold start, client reference modules (
"use client"components) are loaded lazily viaasync
import()through@vitejs/plugin-rsc'ssetRequireModule({ load }). WhenhandleSsrruns
renderToReadableStreamon the first request, React SSR tries to render the HTML shellbut the client component imports haven't resolved yet. With no
<Suspense>boundary wrappingthe root, React cannot render a fallback and rejects with
undefined, causing a 500.All subsequent requests work because
memoize()insetRequireModulecaches resolved modules.Fix
Eagerly preload all client reference modules at the start of
handleSsr, beforerenderToReadableStreamruns:The
virtual:vite-rsc/client-referencesmodule (provided by@vitejs/plugin-rsc) exposesthe map of all client component IDs. The
__vite_rsc_client_require__global is already setby
initialize()beforehandleSsris called.Scope
packages/vinext/src/server/app-dev-server.ts— insidegenerateSsrEntry()template@vitejs/plugin-rscor any other packageTesting
Verified on a production vinext app with 11 client component references:
Notes
memoize()cache means only the first call per IDdoes actual work. The overhead on subsequent requests is negligible (synchronous Map lookups).
?.defaultand?.catchguards ensure the fix is safe if@vitejs/plugin-rscchanges its export shape in the future.
generateSsrEntry()), so itaffects both dev and production SSR.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.