| 1 | # React Server Components (RSC) |
| 2 | |
| 3 | React Router's RSC support is unstable and exists in two variants: |
| 4 | |
| 5 | - **RSC Framework Mode**: Framework Mode with the unstable RSC Vite plugin. |
| 6 | - **RSC Data Mode**: lower-level RSC runtime APIs and manual bundler/server integration. |
| 7 | |
| 8 | Use this reference in addition to `framework-mode.md` or `data-mode.md` after the main skill identifies an RSC app. |
| 9 | |
| 10 | ## Read the Local RSC Docs |
| 11 | |
| 12 | Start with: |
| 13 | |
| 14 | ```txt |
| 15 | react-router/docs/how-to/react-server-components.md |
| 16 | ``` |
| 17 | |
| 18 | Then read the relevant base mode docs: |
| 19 | |
| 20 | ```txt |
| 21 | react-router/docs/start/framework/ |
| 22 | react-router/docs/start/data/ |
| 23 | ``` |
| 24 | |
| 25 | RSC docs may describe differences from non-RSC mode rather than repeating every Framework/Data concept, so keep both layers in mind. |
| 26 | |
| 27 | ## Detect RSC Framework Mode |
| 28 | |
| 29 | Look for: |
| 30 | |
| 31 | - `unstable_reactRouterRSC` imported from `@react-router/dev/vite` |
| 32 | - `@vitejs/plugin-rsc` |
| 33 | - `vite.config.ts` with `plugins: [reactRouterRSC(), rsc()]` |
| 34 | - Framework route modules plus RSC route exports |
| 35 | - RSC entry files such as `entry.rsc` |
| 36 | |
| 37 | RSC Framework Mode uses a different Vite plugin from non-RSC Framework Mode. Do not swap it for the regular `reactRouter()` plugin. |
| 38 | |
| 39 | ## Detect RSC Data Mode |
| 40 | |
| 41 | Look for: |
| 42 | |
| 43 | - `unstable_RSCRouteConfig` |
| 44 | - route config passed to lower-level RSC APIs |
| 45 | - APIs such as `unstable_matchRSCServerRequest`, `unstable_routeRSCServerRequest`, `unstable_RSCHydratedRouter`, or `unstable_RSCStaticRouter` |
| 46 | - custom bundler/server setup around RSC |
| 47 | |
| 48 | RSC Data Mode is more manual than RSC Framework Mode. Match the app's bundler and server abstractions before changing routes or entries. |
| 49 | |
| 50 | ## RSC Route Module Differences |
| 51 | |
| 52 | In RSC Framework Mode, many normal Framework Mode concepts still apply, but routes can use server component exports. |
| 53 | |
| 54 | Important route-module concepts from the RSC docs include: |
| 55 | |
| 56 | - `ServerComponent` instead of the usual client `default` component |
| 57 | - `ServerErrorBoundary` paired with `ErrorBoundary` |
| 58 | - `ServerLayout` paired with `Layout` |
| 59 | - `ServerHydrateFallback` paired with `HydrateFallback` |
| 60 | - server-rendered React elements returned from loaders/actions |
| 61 | |
| 62 | A route module cannot export both the normal client component and its server component counterpart for the same role. Read the RSC docs before adding these exports. |
| 63 | |
| 64 | ## Client/Server Boundaries |
| 65 | |
| 66 | RSC code must respect React's client/server split: |
| 67 | |
| 68 | - Use `"use client"` for components that need hooks, browser APIs, or event handlers. |
| 69 | - Use server-only modules for server data access and secrets. |
| 70 | - In RSC Framework Mode, prefer the `server-only` and `client-only` boundary imports described in the docs. |
| 71 | - Do not assume `.server`/`.client` file naming works the same way in RSC Framework Mode; read the RSC docs before relying on those conventions. |
| 72 | |
| 73 | ## Data Loading in RSC |
| 74 | |
| 75 | RSC changes where data can be loaded: |
| 76 | |
| 77 | - Server Components can fetch data directly on the server. |
| 78 | - Loaders/actions may still exist and can have RSC-specific behavior. |
| 79 | - Client components still need client-safe data and cannot directly access server-only modules. |
| 80 | |
| 81 | When choosing between a server component fetch, a loader, and a client loader/action, follow the RSC docs and match existing app patterns. |
| 82 | |
| 83 | ## Stability |
| 84 | |
| 85 | RSC APIs are explicitly unstable. Before implementing or refactoring RSC code: |
| 86 | |
| 87 | - Check the installed React Router version. |
| 88 | - Check the installed `@vitejs/plugin-rsc` version. |
| 89 | - Read the app's existing RSC entry/config files. |
| 90 | - Prefer minimal changes that match current patterns. |