Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/vinext/src/server/app-dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2296,6 +2296,7 @@ import { setNavigationContext, ServerInsertedHTMLContext } from "next/navigation
import { runWithNavigationContext as _runWithNavCtx } from "vinext/navigation-state";
import { safeJsonStringify } from "vinext/html";
import { createElement as _ssrCE } from "react";
import * as _clientRefs from "virtual:vite-rsc/client-references";

/**
* Collect all chunks from a ReadableStream into an array of text strings.
Expand Down Expand Up @@ -2420,6 +2421,21 @@ function createRscEmbedTransform(embedStream) {
* and the data needs to be passed to SSR since they're separate module instances.
*/
export async function handleSsr(rscStream, navContext, fontData) {
// Eagerly preload all client reference modules before SSR rendering.
// On the first request after server start, client component modules are
// loaded lazily via async import(). Without this preload, React's
// renderToReadableStream rejects because the shell can't resolve client
// components synchronously (there is no Suspense boundary wrapping the
// root). The memoized require cache ensures this is only async on the
// very first call; subsequent requests resolve from cache immediately.
if (_clientRefs?.default && globalThis.__vite_rsc_client_require__) {
await Promise.all(
Object.keys(_clientRefs.default).map((id) =>
globalThis.__vite_rsc_client_require__(id).catch?.(() => {})
)
);
}

// Wrap in a navigation ALS scope for per-request isolation in the SSR
// environment. The SSR environment has separate module instances from RSC,
// so it needs its own ALS scope.
Expand Down
Loading