Skip to content

Commit de5b53a

Browse files
docs: comprehensive RSC API documentation and registration consolidation (#3140)
Comprehensive documentation overhaul for React Server Components APIs (registerServerComponent, wrapServerComponentRenderer, RSCRoute, useRSC) and component registration/auto-bundling. Also fixes render-function and view-helper inaccuracies from #2911. Key changes: - Rewrite inside-client-components.md into a professional reference - Create canonical "Auto-Bundling with React Server Components" section - Fix incorrect imports (named → default) in installation.md and updating.md - Remove stale registerServerComponent config object API - Fix render-functions.md: component types, compatibility matrix, async+ExecJS, Legacy markers, clientProps merge, isServerRenderHash trigger keys - Fix view-helpers-api.md: raise_on_prerender_error default, react_component_hash forced prerender, renderer function docs, stream_react_component constraints - Fix migrating-to-rsc.md wrong registerServerComponent signature - Fix rsc-preparing-app.md stale immediate_hydration reference - Cross-reference docs to reduce duplication across 6+ files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 73f9085 commit de5b53a

11 files changed

Lines changed: 574 additions & 338 deletions

docs/oss/api-reference/view-helpers-api.md

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ Uncommonly used options:
2424
id: nil,
2525
```
2626

27-
- **component_name:** Can be a React component, created using a React Function Component, an ES6 class or a Render-Function that returns a React component (or, only on the server side, an object with shape `{ renderedHtml, clientProps? }`), or a "renderer function" that manually renders a React component to the DOM (client-side only). Note, a "renderer function" is a special type of "Render-Function." A "renderer function" takes a 3rd param of a DOM ID. The legacy `redirectLocation` and `routeError` return fields are still supported but deprecated — see the [Render-Functions Guide](../core-concepts/render-functions.md#8-redirect-information-legacy) for modern alternatives.
27+
- **component_name:** Can be a React component, created using a React Function Component, an ES6 class or a Render-Function that returns a React component (or, only on the server side, an object with shape `{ renderedHtml, clientProps?, redirectLocation?, routeError? }`), or a "renderer function" that manually renders a React component to the DOM (client-side only). Note, a "renderer function" is a special type of "Render-Function." A "renderer function" takes a 3rd param of a DOM ID.
28+
> If your render function returns a hash with multiple HTML strings (e.g., `{ renderedHtml: { componentHtml, title, metaTags } }`), `react_component` raises a `ReactOnRails::Error` telling you to use [`react_component_hash`](#react_component_hash) instead. `react_component` is for rendering a single HTML result; `react_component_hash` is for rendering multiple HTML strings to place in different parts of the page.
2829
All options except `props, id, html_options` will inherit from your `react_on_rails.rb` initializer, as described [here](../configuration/README.md).
2930
- **general options:**
3031
- **props:** Ruby Hash which contains the properties to pass to the React object, or a JSON string. If you pass a string, we'll escape it for you.
@@ -39,7 +40,7 @@ Uncommonly used options:
3940
- **options if prerender (server rendering) is true:**
4041
- **replay_console:** Default is true. False will disable echoing server-rendering logs to the browser. While this can make troubleshooting server rendering difficult, so long as you have the configuration of `logging_on_server` set to true, you'll still see the errors on the server.
4142
- **logging_on_server:** Default is true. True will log JS console messages and errors to the server.
42-
- **raise_on_prerender_error:** Default is false. True will throw an error on the server side rendering. Your controller will have to handle the error.
43+
- **raise_on_prerender_error:** Default is `Rails.env.development?` (true in development, false in production). True will throw an error on server-side rendering. Your controller will have to handle the error.
4344
- **`clientProps` merge behavior:** If a prerender result includes `clientProps`, React on Rails merges them into the generated client hydration props payload (`props.merge(clientProps)`). The original `props:` value must be a Ruby Hash or a JSON string representing an object.
4445

4546
---
@@ -49,13 +50,14 @@ Uncommonly used options:
4950
> **React 19 Alternative:** For metadata use cases (page titles, meta tags, canonical URLs), consider using [React 19 Native Metadata](../building-features/react-19-native-metadata.md) with `react_component` or `stream_react_component` instead. React 19 natively hoists `<title>`, `<meta>`, and `<link>` tags to `<head>`, eliminating the need for a render-function and `react_component_hash`. See the [migration guide](../building-features/react-19-native-metadata.md#migration-guide) for step-by-step instructions.
5051
5152
`react_component_hash` is used to return multiple HTML strings for server rendering, such as for
52-
adding meta-tags to a page. It is exactly like react_component except for the following:
53+
adding meta-tags to a page. It is exactly like `react_component` except for the following:
5354

54-
1. **`prerender: true` is always forced** — even if you pass `prerender: false`, it is silently overwritten. This helper only makes sense for server rendering.
55-
2. Your JavaScript Render-Function for server rendering must return an Object with a `renderedHtml` property containing `componentHtml` and any other keys.
56-
3. Your view code must expect an object and not a string.
57-
4. Cannot be used with renderer functions (3-parameter functions) — these are client-only.
58-
5. The `immediate_hydration` option is no longer supported — if passed, it will be ignored with a deprecation warning.
55+
1. **`prerender: true` is forced**, not defaulted. This helper always prerenders on the server — passing `prerender: false` has no effect. Client-only rendering is incompatible with the "return multiple HTML strings" use case, so the option cannot be disabled.
56+
2. Your JavaScript Render-Function for server rendering must return an Object rather than a React Component. The object must have shape `{ renderedHtml: { componentHtml, ...otherKeys } }`, where:
57+
- **`componentHtml` is mandatory.** Missing it raises `ReactOnRails::Error` with a message pointing to this requirement. This key contains the main server-rendered HTML that gets placed where the helper is called.
58+
- All other keys are optional and are returned to your view as `html_safe` strings, ready to be inserted anywhere in the layout (meta tags in `<head>`, sidebars, etc.).
59+
3. Your view code must expect an object and not a string. Access keys with `react_component_hash_result["componentHtml"]`, `["title"]`, etc.
60+
4. If the render function returns a string instead of an object, the helper raises an error telling you to return a render function that produces a hash.
5961

6062
Here is an example of ERB view code:
6163

@@ -92,19 +94,14 @@ You can call `rails_context` or `rails_context(server_side: true|false)` from yo
9294

9395
---
9496

95-
For a complete table of which component/return types work with each helper, see the [Compatibility Matrix](../core-concepts/render-functions.md#compatibility-matrix) in the Render-Functions guide.
96-
97-
---
98-
9997
### Renderer Functions (function that will call ReactDOM.render or ReactDOM.hydrate)
10098

101-
A "renderer function" is a Render-Function that accepts three arguments (rather than 2): `(props, railsContext, domNodeId) => { ... }`. Instead of returning a React component, a renderer is responsible for installing a callback that will call `ReactDOM.render` (in React 16+, `ReactDOM.hydrate`) to render a React component into the DOM. The "renderer function" is called at the same time the document ready event would instantiate the React components into the DOM.
99+
A **renderer function** is a Render-Function that declares **three** parameters: `(props, railsContext, domNodeId) => { ... }`. React on Rails detects renderer functions purely by parameter count (`Function.length === 3`) — the names don't matter. Instead of returning a React component, a renderer function is responsible for mounting the React tree itself by calling `ReactDOM.hydrateRoot` (for SSR'd HTML) or `ReactDOM.createRoot(...).render(...)` (for empty containers) against the DOM node identified by `domNodeId`. The renderer function is invoked at the point where React on Rails would normally mount the component automatically.
102100

103-
Why would you want to call `ReactDOM.hydrate` yourself? One possible use case is code splitting. In a nutshell, you don't want to load the React component on the DOM node yet. So you want to install some handler that will call `ReactDOM.hydrate` at a later time. In the case of code splitting with server rendering, the server-rendered code has any async code loaded and used to server render. Thus, the client code must also fully load any async code before server rendering. Otherwise, the client code would first render partially, not matching the server rendering, and then a second later, the full code would render, resulting in an unpleasant flashing on the screen.
101+
Why would you want to take over mounting yourself? One use case is code splitting: you may want to defer mounting a component until its code chunk has loaded, or until the container scrolls into view, instead of mounting it eagerly on page load. For modern code splitting with server-side rendering, see the [React on Rails Pro loadable-components guide](../building-features/code-splitting.md).
104102

105-
For modern code splitting with server-side rendering, see the [React on Rails Pro loadable-components guide](../building-features/code-splitting.md).
106-
107-
Renderer functions are not meant to be used on the server since there's no DOM on the server. Instead, use a Render-Function. Attempting to server render with a renderer function will throw an error.
103+
> [!IMPORTANT]
104+
> **Renderer functions are strictly client-only.** There is no DOM on the server, so a renderer function cannot produce SSR output. React on Rails detects renderer functions at registration time and will throw a descriptive error like `Detected a renderer while server rendering component 'X'. See https://reactonrails.com/docs/core-concepts/render-functions for more information.` if you attempt to use one with `react_component(... prerender: true)`, `react_component_hash` (which forces prerendering), or `stream_react_component` (which is server-streaming only). For rendering that needs to run on the server, use a regular render function instead.
108105
109106
---
110107

@@ -160,11 +157,11 @@ Progressive server-side rendering using React 18+ streaming with `renderToPipeab
160157
- Progressive page loading with Suspense boundaries
161158
- Better perceived performance
162159

163-
> [!IMPORTANT]
164-
> `stream_react_component` always forces `prerender: true`, even if you pass a different value. The `immediate_hydration` option is no longer supported and will be ignored with a warning if passed. It only works with React components or render functions that return React components — it does not support render functions returning `{ renderedHtml }` objects.
165-
166160
See the [Streaming Server Rendering guide](../building-features/streaming-server-rendering.md) for usage details.
167161

162+
> [!IMPORTANT]
163+
> `stream_react_component` always forces `prerender: true` — passing `prerender: false` has no effect. It only supports React components and render functions that return React components; render functions returning a `{ renderedHtml }` hash are incompatible (see [compatibility matrix](../core-concepts/render-functions.md#compatibility-matrix-component-types-and-ruby-helpers)).
164+
168165
### rsc_payload_react_component
169166

170167
Renders React Server Component (RSC) payloads in NDJSON format for client-side consumption. Used in conjunction with RSC support to enable:

0 commit comments

Comments
 (0)