"use client" components, React serializes the tree into a flight payload — a streaming format that references client components by ID instead of embedding their code.1{ "id": "abc123", "name": "default", "chunks": [], "async": true }
id is a referenceKey computed as hash(relativeFilePath) during the production build. The name is the export name (default, MyComponent, etc.). No chunk URLs appear in the flight payload — only this stable ID.@vitejs/plugin-rsc normalizes client reference IDs differently per environment:referenceKey = hashString(relativeFilePath) — a deterministic hash of the file's path relative to the project root. Same source tree → same hash, every time.abc123), not a chunk URL. The chunk URL resolution happens entirely on the client side.@vitejs/plugin-rsc generates a client references map that gets compiled into the client bundle:1234567// Baked into the client JS bundle at build time export default { "abc123": async () => { const m = await import("./user-components-f8a2c1.js") return m.export_abc123 }, }
123456789New server renders JSX → flight payload contains ref "abc123" ↓ Old client's React runtime calls __vite_rsc_require__("abc123") ↓ Old client looks up "abc123" in its OWN baked-in references map ↓ Finds it → import("./user-components-f8a2c1.js") ← old chunk URL ↓ CDN still serves the old chunk → component loads ✅
user-components-f8a2c1.js) will continue serving old chunks.hash(filePath)#exportName) is stable — same file path, same ID across deploys"use client" component that didn't exist in the old build. The old client's references map won't have that ID.getDeploymentId(). This is useful for analytics, logging, and cache keys — but it's not used to block requests.@vitejs/plugin-rsc encrypts bound arguments (closure-captured values) in server actions using AES-256-GCM. This protects server-side data that gets serialized into the RSC payload when an inline "use server" function captures variables from a server component.RSC_ENCRYPTION_KEY environment variable to a stable base64-encoded 32-byte key."use server" files) have no closures, so there's nothing to encrypt.123456789101112┌──────────────────────────────────────────────────────────────────────┐ │ What happens across deployments? │ ├──────────────────────┬───────────────────────────────────────────────┤ │ Client navigation │ Executes normally on new server │ │ Server action call │ Executes normally on new server │ │ Action returns JSX │ Old client resolves refs from own map ✅ │ │ Action bound args │ Needs stable RSC_ENCRYPTION_KEY if used │ │ New component in JSX │ Fails if component didn't exist in old build │ │ Client ref IDs │ Stable (hash of file path) │ │ Client chunk URLs │ Old chunks served by CDN │ │ React instance │ Always one — no duplicates │ └──────────────────────┴───────────────────────────────────────────────┘