diff --git a/packages/plugin-rsc/README.md b/packages/plugin-rsc/README.md index acc1bc5e8..f4fcc44de 100644 --- a/packages/plugin-rsc/README.md +++ b/packages/plugin-rsc/README.md @@ -4,10 +4,10 @@ This package provides [React Server Components](https://react.dev/reference/rsc/ ## Features -- **Framework-less RSC experience**: The plugin implements [RSC conventions](https://react.dev/reference/rsc/server-components) and provides low level `react-server-dom` runtime API without framework-specific abstractions. -- **CSS support**: CSS is automatically code-split both at client and server components and they are injected upon rendering. +- **Framework-agnostic**: The plugin implements [RSC bundler features](https://react.dev/reference/rsc/server-components) and provides low level RSC runtime (`react-server-dom`) API without framework-specific abstractions. +- **Runtime-agnostic**: Built on [Vite environment API](https://vite.dev/guide/api-environment.html) and works with other runtimes (e.g., [`@cloudflare/vite-plugin`](https://github.com/cloudflare/workers-sdk/tree/main/packages/vite-plugin-cloudflare)). - **HMR support**: Enables editing both client and server components without full page reloads. -- **Runtime agnostic**: Built on [Vite environment API](https://vite.dev/guide/api-environment.html) and works with other runtimes (e.g., [`@cloudflare/vite-plugin`](https://github.com/cloudflare/workers-sdk/tree/main/packages/vite-plugin-cloudflare)). +- **CSS support**: CSS is automatically code-split both at client and server components and they are injected upon rendering. ## Getting Started @@ -19,14 +19,17 @@ npx degit vitejs/vite-plugin-react/packages/plugin-rsc/examples/starter my-app ## Examples -- [`./examples/starter`](./examples/starter) - - This example provides an in-depth overview of API with inline comments to explain how they function within RSC-powered React application. -- [`./examples/react-router`](./examples/react-router) - - This demonstrates how to integrate [experimental React Router RSC API](https://remix.run/blog/rsc-preview). React Router now provides [official RSC support](https://reactrouter.com/how-to/react-server-components), so it's recommended to follow React Router's official documentation for the latest integration. -- [`./examples/basic`](./examples/basic) - - This is mainly used for e2e testing and include various advanced RSC usages (e.g. `"use cache"` example). -- [`./examples/ssg`](./examples/ssg) - - Static site generation (SSG) example with MDX and client components for interactivity. +**Start here:** [`./examples/starter`](./examples/starter) - Recommended for understanding the plugin + +- Provides an in-depth overview of API with inline comments to explain how they function within RSC-powered React application. + +**Integration examples:** + +- [`./examples/basic`](./examples/basic) - Advanced RSC features and testing + - This is mainly used for e2e testing and includes various advanced RSC usages (e.g. `"use cache"` example). +- [`./examples/ssg`](./examples/ssg) - Static site generation with MDX and client components for interactivity. +- [`./examples/react-router`](./examples/react-router) - React Router RSC integration + - Demonstrates how to integrate [experimental React Router RSC API](https://remix.run/blog/rsc-preview). React Router now provides [official RSC support](https://reactrouter.com/how-to/react-server-components), so it's recommended to follow React Router's official documentation for the latest integration. ## Basic Concepts @@ -132,7 +135,7 @@ import * as ReactServer from '@vitejs/plugin-rsc/rsc' // re-export of react-serv // the plugin assumes `rsc` entry having default export of request handler export default async function handler(request: Request): Promise { - // serialization React VDOM to RSC stream + // serialize React VDOM to RSC stream const root = ( @@ -193,51 +196,26 @@ export async function handleSsr(rscStream: ReadableStream) { - [`entry.browser.tsx`](./examples/starter/src/framework/entry.browser.tsx) ```tsx -import * as ReactClient from "@vitejs/plugin-rsc/browser"; // re-export of react-server-dom/client.browser -import * as ReactDOMClient from "react-dom/client"; +import * as ReactClient from '@vitejs/plugin-rsc/browser' // re-export of react-server-dom/client.browser +import * as ReactDOMClient from 'react-dom/client' async function main() { // fetch and deserialize RSC stream back to React VDOM - const rscResponse = await fetch(window.location.href + ".rsc); - const root = await ReactClient.createFromReadableStream(rscResponse.body); + const rscResponse = await fetch(window.location.href + '.rsc') + const root = await ReactClient.createFromReadableStream(rscResponse.body) // hydration (traditional CSR) - ReactDOMClient.hydrateRoot(document, root); + ReactDOMClient.hydrateRoot(document, root) } -main(); +main() ``` -## `react-server-dom` API - -### `@vitejs/plugin-rsc/rsc` - -This module re-exports RSC runtime API provided by `react-server-dom/server.edge` and `react-server-dom/client.edge` such as: - -- `renderToReadableStream`: RSC serialization (React VDOM -> RSC stream) -- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM). This is also available on rsc environment itself. For example, it allows saving serailized RSC and deserializing it for later use. -- `decodeAction/decodeReply/decodeFormState/loadServerAction/createTemporaryReferenceSet` -- `encodeReply/createClientTemporaryReferenceSet` - -### `@vitejs/plugin-rsc/ssr` - -This module re-exports RSC runtime API provided by `react-server-dom/client.edge` - -- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM) - -### `@vitejs/plugin-rsc/browser` - -This module re-exports RSC runtime API provided by `react-server-dom/client.browser` - -- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM) -- `createFromFetch`: a robust way of `createFromReadableStream((await fetch("...")).body)` -- `encodeReply/setServerCallback`: server function related... - ## Environment helper API The plugin provides an additional helper for multi environment interaction. -### available on `rsc` or `ssr` environment +### Available on `rsc` or `ssr` environment #### `import.meta.viteRsc.loadModule` @@ -260,7 +238,7 @@ ssrModule.renderHTML(...); export function renderHTML(...) {} ``` -### available on `rsc` environment +### Available on `rsc` environment #### `import.meta.viteRsc.loadCss` @@ -287,7 +265,7 @@ export function ServerPage() { } ``` -Where specifying `loadCss()`, it will collect css through the server module resolved by ``. +When specifying `loadCss()`, it will collect css through the server module resolved by ``. ```tsx // virtual:my-framework-helper @@ -324,7 +302,7 @@ export function Page(props) { return
...
} -// my-route.css?vite-rsc-css-export=Page +// my-route.tsx?vite-rsc-css-export=Page function Page(props) { return
...
} @@ -341,14 +319,13 @@ function __Page(props) { export { __Page as Page } ``` -### available on `ssr` environment +### Available on `ssr` environment #### `import.meta.viteRsc.loadBootstrapScriptContent("index")` This provides a raw js code to execute a browser entry file specified by `environments.client.build.rollupOptions.input.index`. This is intended to be used with React DOM SSR API, such as [`renderToReadableStream`](https://react.dev/reference/react-dom/server/renderToReadableStream) ```js -import bootstrapScriptContent from 'virtual:vite-rsc/bootstrap-script-content' import { renderToReadableStream } from 'react-dom/server.edge' const bootstrapScriptContent = @@ -358,7 +335,7 @@ const htmlStream = await renderToReadableStream(reactNode, { }) ``` -### available on `client` environment +### Available on `client` environment #### `rsc:update` event @@ -420,6 +397,31 @@ export default defineConfig({ }) ``` +## RSC runtime (react-server-dom) API + +### `@vitejs/plugin-rsc/rsc` + +This module re-exports RSC runtime API provided by `react-server-dom/server.edge` and `react-server-dom/client.edge` such as: + +- `renderToReadableStream`: RSC serialization (React VDOM -> RSC stream) +- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM). This is also available on rsc environment itself. For example, it allows saving serialized RSC and deserializing it for later use. +- `decodeAction/decodeReply/decodeFormState/loadServerAction/createTemporaryReferenceSet` +- `encodeReply/createClientTemporaryReferenceSet` + +### `@vitejs/plugin-rsc/ssr` + +This module re-exports RSC runtime API provided by `react-server-dom/client.edge` + +- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM) + +### `@vitejs/plugin-rsc/browser` + +This module re-exports RSC runtime API provided by `react-server-dom/client.browser` + +- `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM) +- `createFromFetch`: a robust way of `createFromReadableStream((await fetch("...")).body)` +- `encodeReply/setServerCallback`: server function related... + ## High level API > [!NOTE] @@ -473,6 +475,10 @@ export function Page() { } ``` +## Canary and Experimental channel releases + +See https://github.com/vitejs/vite-plugin-react/pull/524 for how to install the package for React [canary](https://react.dev/community/versioning-policy#canary-channel) and [experimental](https://react.dev/community/versioning-policy#all-release-channels) usages. + ## Credits This project builds on fundamental techniques and insights from pioneering Vite RSC implementations.