You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
React Router provides a set of APIs for integrating with RSC-compatible bundlers, allowing you to leverage [Server Components][react-server-components-doc] and [Server Functions][react-server-functions-doc] in your React Router applications.
24
24
25
+
If you're unfamiliar with these React features, we recommend reading the official [Server Components documentation][react-server-components-doc] before using React Router's RSC APIs.
26
+
27
+
RSC support is available in both Framework Mode and Data Mode. For more information on the difference between these modes, see the [Picking a Mode][picking-a-mode] guide.
28
+
25
29
## Quick Start
26
30
27
31
The quickest way to get started is with one of our templates.
28
32
29
-
These templates come with React Router RSC APIs already configured with the respective bundler, offering you out of the box features such as:
33
+
These templates come with React Router RSC APIs already configured, offering you out of the box features such as:
- Server Functions (via [`"use server"`][use-server-docs] directive)
35
39
36
-
**Parcel Template**
40
+
### RSC Framework Mode Template
37
41
38
-
The [parcel template][parcel-rsc-template] uses the official React `react-server-dom-parcel` plugin.
42
+
The [RSC Framework Mode template][framework-rsc-template] uses the unstable React Router RSC Vite plugin along with the experimental [`@vitejs/plugin-rsc` plugin][vite-plugin-rsc].
Most APIs and features in RSC Framework Mode are the same as non-RSC Framework Mode, so this guide will focus on the differences.
67
+
68
+
### New React Router RSC Vite Plugin
69
+
70
+
RSC Framework Mode uses a different Vite plugin than non-RSC Framework Mode, currently exported as `unstable_reactRouterRSC`.
71
+
72
+
This new Vite plugin also has a peer dependency on the experimental `@vitejs/plugin-rsc` plugin. Note that the `@vitejs/plugin-rsc` plugin should be placed after the React Router RSC plugin in your Vite config.
The RSC Framework Mode server build file (`build/server/index.js`) now exports a `default` request handler function (`(request: Request) => Promise<Response>`) for document/data requests.
87
+
88
+
If needed, you can convert this into a [standard Node.js request listener][node-request-listener] for use with Node's built-in `http.createServer` function (or anything that supports it, e.g. [Express][express]) by using the `createRequestListener` function from [@remix-run/node-fetch-server][node-fetch-server].
In RSC Framework Mode, loaders and actions can now return React elements along with other data. These elements will only ever be rendered on the server.
114
+
115
+
```tsx
116
+
importtype { Route } from"./+types/route";
117
+
118
+
exportasyncfunction loader() {
119
+
return {
120
+
message: "Message from the server!",
121
+
element: <p>Element from the server!</p>,
122
+
};
123
+
}
124
+
125
+
exportdefaultfunction Route({
126
+
loaderData,
127
+
}:Route.ComponentProps) {
128
+
return (
129
+
<>
130
+
<h1>{loaderData.message}</h1>
131
+
{loaderData.element}
132
+
</>
133
+
);
134
+
}
135
+
```
136
+
137
+
If you need to use client-only features (e.g. [Hooks][hooks], event handlers) within React elements returned from loaders/actions, you'll need to extract components using these features into a [client module][use-client-docs]:
138
+
139
+
```tsx filename=src/routes/counter/counter.tsx
140
+
"use client";
141
+
142
+
exportfunction Counter() {
143
+
const [count, setCount] =useState(0);
144
+
return (
145
+
<buttononClick={() =>setCount(count+1)}>
146
+
Count: {count}
147
+
</button>
148
+
);
149
+
}
150
+
```
151
+
152
+
```tsx filename=src/routes/counter/route.tsx
153
+
importtype { Route } from"./+types/route";
154
+
import { Counter } from"./counter";
155
+
156
+
exportasyncfunction loader() {
157
+
return {
158
+
message: "Message from the server!",
159
+
element: (
160
+
<>
161
+
<p>Element from the server!</p>
162
+
<Counter />
163
+
</>
164
+
),
165
+
};
166
+
}
167
+
168
+
exportdefaultfunction Route({
169
+
loaderData,
170
+
}:Route.ComponentProps) {
171
+
return (
172
+
<>
173
+
<h1>{loaderData.message}</h1>
174
+
{loaderData.element}
175
+
</>
176
+
);
177
+
}
178
+
```
179
+
180
+
### Server Component Routes
181
+
182
+
If a route exports a `ServerComponent` instead of the typical `default` component export, this component along with other route components (`ErrorBoundary`, `HydrateFallback`, `Layout`) will be server components rather than the usual client components.
183
+
184
+
```tsx
185
+
importtype { Route } from"./+types/route";
186
+
import { Outlet } from"react-router";
187
+
import { getMessage } from"./message";
188
+
189
+
exportasyncfunction loader() {
190
+
return {
191
+
message: awaitgetMessage(),
192
+
};
193
+
}
194
+
195
+
exportfunction ServerComponent({
196
+
loaderData,
197
+
}:Route.ComponentProps) {
198
+
return (
199
+
<>
200
+
<h1>Server Component Route</h1>
201
+
<p>Message from the server: {loaderData.message}</p>
202
+
<Outlet />
203
+
</>
204
+
);
205
+
}
206
+
```
207
+
208
+
If you need to use client-only features (e.g. [Hooks][hooks], event handlers) within a server-first route, you'll need to extract components using these features into a [client module][use-client-docs]:
209
+
210
+
```tsx filename=src/routes/counter/counter.tsx
211
+
"use client";
212
+
213
+
exportfunction Counter() {
214
+
const [count, setCount] =useState(0);
215
+
return (
216
+
<buttononClick={() =>setCount(count+1)}>
217
+
Count: {count}
218
+
</button>
219
+
);
220
+
}
221
+
```
222
+
223
+
```tsx filename=src/routes/counter/route.tsx
224
+
import { Counter } from"./counter";
225
+
226
+
exportfunction ServerComponent() {
227
+
return (
228
+
<>
229
+
<h1>Counter</h1>
230
+
<Counter />
231
+
</>
232
+
);
233
+
}
234
+
```
235
+
236
+
### `.server`/`.client` Modules
237
+
238
+
To avoid confusion with React's `"use server"` and `"use client"` directives, support for [`.server` modules][server-modules] and [`.client` modules][client-modules] is no longer built-in.
239
+
240
+
If you need either of these features, we recommend using the [`vite-env-only` plugin][vite-env-only] directly. For example, to ensure `.server` modules aren't accidentally included in the client build:
MDX routes are supported in RSC Framework Mode when using `@mdx-js/rollup` v3.1.1+.
262
+
263
+
Note that any components exported from an MDX route must also be valid in RSC environments, meaning that they cannot use client-only features like [Hooks][hooks]. Any components that need to use these features should be extracted into a [client module][use-client-docs].
264
+
265
+
### Unsupported Config Options
266
+
267
+
For the initial unstable release, the following options from `react-router.config.ts` are not yet supported in RSC Framework Mode:
268
+
269
+
-`buildEnd`
270
+
-`prerender`
271
+
-`presets`
272
+
-`routeDiscovery`
273
+
-`serverBundles`
274
+
-`ssr: false` (SPA Mode)
275
+
-`future.unstable_splitRouteModules`
276
+
-`future.unstable_subResourceIntegrity`
277
+
278
+
Custom build entry files are also not yet supported.
279
+
280
+
## RSC Data Mode
281
+
282
+
The RSC Framework Mode APIs described above are built on top of lower-level RSC Data Mode APIs.
283
+
284
+
RSC Data Mode is missing some of the features of RSC Framework Mode (e.g. `routes.ts` config and file system routing, HMR and Hot Data Revalidation), but is more flexible and allows you to integrate with your own bundler and server abstractions.
53
285
54
286
### Configuring Routes
55
287
@@ -238,7 +470,7 @@ export default function Root() {
238
470
}
239
471
```
240
472
241
-
##Configuring RSC with React Router
473
+
### Bundler Configuration
242
474
243
475
React Router provides several APIs that allow you to easily integrate with RSC-compatible bundlers, useful if you are using React Router Data Mode to make your own [custom framework][custom-framework].
244
476
@@ -303,7 +535,7 @@ Relevant APIs:
303
535
304
536
### Parcel
305
537
306
-
See the [Parcel RSC docs][parcel-rsc-doc] for more information. You can also refer to our [Parcel RSC Parcel template][parcel-rsc-template] to see a working version.
538
+
See the [Parcel RSC docs][parcel-rsc-doc] for more information. You can also refer to our [Parcel RSC Data Mode template][parcel-rsc-template] to see a working version.
307
539
308
540
In addition to `react`, `react-dom`, and `react-router`, you'll need the following dependencies:
See the [Vite RSC docs][vite-rsc-doc] for more information. You can also refer to our [Vite RSC template][vite-rsc-template] to see a working version.
788
+
See the [@vitejs/plugin-rscdocs][vite-plugin-rsc] for more information. You can also refer to our [Vite RSC Data Mode template][vite-rsc-template] to see a working version.
557
789
558
790
In addition to `react`, `react-dom`, and `react-router`, you'll need the following dependencies:
0 commit comments