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
Add RSC and Node Renderer documentation to CLAUDE.md and README.md
Document the three-bundle architecture (client, server SSR, RSC), Node
Renderer setup requirements, VM sandbox constraints, RSC component
classification rules, and common troubleshooting patterns. Update README
with current version targets, RSC section, expanded config file list,
and all six Procfile.dev processes.
Motivated by the debugging challenges in PR #723 where undocumented
constraints (VM sandbox lacks require/MessageChannel, 'use client'
classification, Node renderer must run for tests) caused significant
debugging time. Filed shakacode/react_on_rails#3076 with upstream
doc suggestions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|**Server (SSR)**|`serverWebpackConfig.js`|`ssr-generated/`| Node renderer VM sandbox |
27
+
|**RSC**|`rscWebpackConfig.js`| RSC output dir | Node renderer (full Node.js) |
28
+
29
+
### Key constraints
30
+
31
+
- The **server bundle runs in a VM sandbox** (`vm.createContext()`), NOT full Node.js. It lacks `require`, `MessageChannel`, `TextEncoder`, and other Node/browser globals.
32
+
- Use `resolve.fallback: false` (NOT `externals`) for Node builtins in the server bundle — the VM has no `require()`, so externalized `require('path')` calls will crash.
33
+
- The **RSC bundle** targets Node.js directly with the `react-server` condition, so Node builtins work normally there.
34
+
- A `BannerPlugin` injects a `MessageChannel` polyfill into the server bundle because `react-dom/server.browser` needs it at module load time.
35
+
36
+
### Build commands
37
+
38
+
```bash
39
+
# Build only the server bundle
40
+
SERVER_BUNDLE_ONLY=yes bin/shakapacker
41
+
42
+
# Build only the RSC bundle
43
+
RSC_BUNDLE_ONLY=true bin/shakapacker
44
+
45
+
# Watch modes (used by Procfile.dev)
46
+
SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch
47
+
RSC_BUNDLE_ONLY=true bin/shakapacker --watch
48
+
```
49
+
50
+
## Node Renderer
51
+
52
+
React on Rails Pro's NodeRenderer must be running for SSR and RSC payload generation.
53
+
54
+
-**Port**: 3800 (configured in `config/initializers/react_on_rails_pro.rb`)
-**Auth**: Requires `RENDERER_PASSWORD` env var (defaults to `local-dev-renderer-password` in dev/test, required with no fallback in production)
57
+
-**Started automatically** by `bin/dev` / `Procfile.dev`
58
+
59
+
### Testing requirement
60
+
61
+
**The Node renderer must be running before `bundle exec rspec`.** Tests will fail with `Net::ReadTimeout` if it is not running. CI starts it as a background process and waits up to 30 seconds for TCP readiness on port 3800.
62
+
63
+
### Enabled environments
64
+
65
+
The renderer is enabled when `Rails.env.local?` (development + test) or `REACT_USE_NODE_RENDERER=true`. Production requires explicit env var configuration.
66
+
67
+
## RSC Component Classification
68
+
69
+
React on Rails Pro auto-classifies components based on the `'use client'` directive:
70
+
71
+
-**With `'use client'`** → registered via `ReactOnRails.register()` (traditional SSR/client component)
72
+
-**Without `'use client'`** → registered via `registerServerComponent()` (React Server Component)
73
+
74
+
### Common gotcha: `.server.jsx` files
75
+
76
+
In this codebase, `.server.jsx` does NOT mean "React Server Component" — it means traditional **server-side rendering** (e.g., `StaticRouter`). If a `.server.jsx` file uses client APIs like `ReactOnRails.getStore()` or React hooks, it **needs** the `'use client'` directive to prevent RSC misclassification. The naming predates RSC and refers to the Rails SSR render path.
Copy file name to clipboardExpand all lines: README.md
+65-16Lines changed: 65 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -83,19 +83,19 @@ You can see this tutorial live here: [http://reactrails.com/](http://reactrails.
83
83
+[Configuration Files](#configuration-files)
84
84
+[Additional Resources](#additional-resources)
85
85
+[Thruster HTTP/2 Proxy](#thruster-http2-proxy)
86
+
+[React Server Components (RSC)](#react-server-components-rsc)
86
87
+[Sass, CSS Modules, and Tailwind CSS integration](#sass-css-modules-and-tailwind-css-integration)
87
88
+[Fonts with SASS](#fonts-with-sass)
88
89
+[Process Management during Development](#process-management-during-development)
89
-
+[Rendering with Express Server](#rendering-with-express-server)
90
-
+[Setup](#setup)
91
90
+[Contributors](#contributors)
92
91
+[About ShakaCode](#about-shakacode)
93
92
+[RubyMine and WebStorm](#rubymine-and-webstorm)
94
93
+[Open Code of Conduct](#open-code-of-conduct)
95
94
96
95
## Demoed Functionality
97
96
98
-
- Example of using the [react_on_rails gem](https://github.com/shakacode/react_on_rails) for easy React + Rspack integration with Rails.
97
+
- Example of using [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/) with the NodeRenderer for server-side rendering.
98
+
- Example of [React Server Components (RSC)](#react-server-components-rsc) with streaming and selective hydration.
99
99
- Example of React with [CSS Modules](http://glenmaddern.com/articles/css-modules) inside Rails using modern Shakapacker/Rspack builds.
100
100
- Example of enabling hot reloading of both JS and CSS (modules) from your Rails app in development mode. Change your code. Save. Browser updates without a refresh!
101
101
- Example of React/Redux with Rails Action Cable.
@@ -110,18 +110,17 @@ You can see this tutorial live here: [http://reactrails.com/](http://reactrails.
@@ -243,6 +245,47 @@ The server automatically benefits from HTTP/2, caching, and compression without
243
245
244
246
For detailed information, troubleshooting, and advanced configuration options, see [docs/thruster.md](docs/thruster.md).
245
247
248
+
## React Server Components (RSC)
249
+
250
+
This project demonstrates React Server Components with React on Rails Pro. Visit `/server-components` to see the demo page.
251
+
252
+
### How It Works
253
+
254
+
The app builds **three separate bundles**:
255
+
256
+
1.**Client bundle** — Browser JavaScript with HMR, built by `clientWebpackConfig.js`
257
+
2.**Server bundle** — Traditional SSR, runs in the Node renderer's VM sandbox, built by `serverWebpackConfig.js`
258
+
3.**RSC bundle** — React Server Components with the `react-server` condition, runs in full Node.js, built by `rscWebpackConfig.js`
259
+
260
+
The [React on Rails Pro NodeRenderer](https://www.shakacode.com/react-on-rails-pro/) runs on port 3800 and handles both SSR rendering and RSC payload generation. A custom `RspackRscPlugin` detects `'use client'` directives in source files and emits the React Flight manifests (`react-client-manifest.json`, `react-server-client-manifest.json`) that React uses to resolve client component references during streaming.
The tutorial makes use of a custom font OpenSans-Light. We're doing this to show how to add assets for the CSS processing. The font files are located under [client/app/assets/fonts](client/app/assets/fonts) and are loaded by both the Rails asset pipeline and the Rspack HMR server.
272
315
273
-
## Process management during development
316
+
## Process Management during Development
274
317
```bash
275
318
bundle exec foreman start -f <Procfile>
276
319
```
277
320
278
-
1.[`Procfile.dev`](Procfile.dev): Starts the Rspack Dev Server and Rails with Hot Reloading.
321
+
1.[`Procfile.dev`](Procfile.dev): Starts all development processes with Hot Reloading:
322
+
-`rescript` — ReScript watch mode
323
+
-`rails` — Rails server via Thruster on port 3000
324
+
-`wp-client` — Client Rspack dev server with HMR
325
+
-`wp-server` — Server Rspack watcher for SSR bundle
326
+
-`wp-rsc` — RSC Rspack watcher for React Server Components bundle
327
+
-`node-renderer` — React on Rails Pro Node renderer on port 3800
279
328
1.[`Procfile.dev-static`](Procfile.dev-static): Starts the Rails server and generates static assets that are used for tests.
0 commit comments