Once the bundled files have been generated in your app/assets/webpack folder, and you have registered your components, you will want to render these components on your Rails views using the included helper method, react_component.
react_component(component_name,
props: {},
prerender: nil)
html_options: {})Uncommonly used options:
trace: nil,
replay_console: nil,
raise_on_prerender_error: nil,
id: nil,-
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.If your render function returns a hash with multiple HTML strings (e.g.,
{ renderedHtml: { componentHtml, title, metaTags } }),react_componentraises aReactOnRails::Errortelling you to usereact_component_hashinstead.react_componentis for rendering a single HTML result;react_component_hashis for rendering multiple HTML strings to place in different parts of the page.All options except
props, id, html_optionswill inherit from yourreact_on_rails.rbinitializer, as described in the configuration documentation. -
general options:
- 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.
- prerender: enable server-side rendering of a component. Set to false when debugging!
- Environment override: set
REACT_ON_RAILS_PRERENDER_OVERRIDE=true|falseto force prerendering on or off globally. Precedence is:REACT_ON_RAILS_PRERENDER_OVERRIDE> component option (prerender:) > initializer default (config.prerender).
- Environment override: set
- auto_load_bundle: will automatically load the bundle for component by calling
append_javascript_pack_tagandappend_stylesheet_pack_tagunder the hood. - id: Id for the div, will be used to attach the React component. This will get assigned automatically if you do not provide an id. Must be unique.
- html_options: Any other HTML options get placed on the added div for the component. For example, you can set a class (or inline style) on the outer div so that it behaves like a span, with the styling of
display:inline-block. You may also use an option oftag: "span"to replace the use of the default DIV tag to be a SPAN tag. - trace: set to true to print additional debugging information in the browser. Defaults to true for development, off otherwise. Only on the client side will you will see the
railsContextand your props. - random_dom_id: True to automatically generate random dom ids when using multiple instances of the same React component on one Rails view.
-
options if prerender (server rendering) is true:
- 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_serverset to true, you'll still see the errors on the server. - logging_on_server: Default is true. True will log JS console messages and errors to the server.
- 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. clientPropsmerge behavior: If a prerender result includesclientProps, React on Rails merges them into the generated client hydration props payload (props.merge(clientProps)). The originalprops:value must be a Ruby Hash or a JSON string representing an object.
- 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
React 19 Alternative: For metadata use cases (page titles, meta tags, canonical URLs), consider using React 19 Native Metadata with
react_componentorstream_react_componentinstead. React 19 natively hoists<title>,<meta>, and<link>tags to<head>, eliminating the need for a render-function andreact_component_hash. See the migration guide for step-by-step instructions.
react_component_hash is used to return multiple HTML strings for server rendering, such as for
adding meta-tags to a page. It is exactly like react_component except for the following:
prerender: trueis forced, not defaulted. This helper always prerenders on the server — passingprerender: falsehas no effect. Client-only rendering is incompatible with the "return multiple HTML strings" use case, so the option cannot be disabled.- 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:componentHtmlis mandatory. Missing it raisesReactOnRails::Errorwith a message pointing to this requirement. This key contains the main server-rendered HTML that gets placed where the helper is called.- All other keys are optional and are returned to your view as
html_safestrings, ready to be inserted anywhere in the layout (meta tags in<head>, sidebars, etc.).
- Your view code must expect an object and not a string. Access keys with
react_component_hash_result["componentHtml"],["title"], etc. - 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.
Here is an example of ERB view code:
<% react_helmet_app = react_component_hash("ReactHelmetApp", prerender: true,
props: { helloWorldData: { name: "Mr. Server Side Rendering"}},
id: "react-helmet-0", trace: true) %>
<% content_for :title do %>
<%= react_helmet_app['title'] %>
<% end %>
<%= react_helmet_app["componentHtml"] %>And here is the JavaScript code:
export default (props, _railsContext) => {
const componentHtml = renderToString(<ReactHelmet {...props} />);
const helmet = Helmet.renderStatic();
const renderedHtml = {
componentHtml,
title: helmet.title.toString(),
};
return { renderedHtml };
};You can call rails_context or rails_context(server_side: true|false) from your controller or view to see what values are in the Rails Context. Pass true or false depending on whether you want to see the server-side or the client-side rails_context. Typically, for computing cache keys, you should leave server_side as the default true. When calling this from a controller method, use helpers.rails_context.
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.
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.
Important
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.
React Router is supported via manual integration, including server-side rendering. See:
- React on Rails docs for React Router
- Examples in spec/dummy/app/views/react_router and follow to the JavaScript code in the spec/dummy/client/app/startup/RouterApp.server.jsx.
- React on Rails Pro loadable-components guide for modern code splitting with server-side rendering.
TanStack Router has a first-class SSR helper through react-on-rails-pro/tanstack-router (requires React on Rails Pro). See TanStack Router guide.
server_render_js(js_expression, options = {})
- js_expression, like 2 + 3, and not a block of js code. If you have more than one line that needs to be executed, wrap it in an IIFE. JS exceptions will be caught, and console messages will be handled properly
- Currently, the only option you may pass is
replay_console(boolean)
This is a helper method that takes any JavaScript expression and returns the output from evaluating it. If you have more than one line that needs to be executed, wrap it in an IIFE. JS exceptions will be caught and console messages handled properly.
The following view helpers are available exclusively with React on Rails Pro. These require a valid React on Rails Pro license and will not be available if the Pro gem is not installed or properly licensed.
Fragment caching helpers that cache React component rendering to improve performance. The API is the same as react_component and react_component_hash, but with these differences:
- The
cache_keytakes the same parameters as any Railscacheview helper. - The props are passed via a block so that evaluation of the props is not done unless the cache is broken.
Example usage:
<%= cached_react_component("App", cache_key: [@user, @post], prerender: true) do
some_slow_method_that_returns_props
end %>Progressive server-side rendering using React 18+ streaming with renderToPipeableStream. This enables:
- Faster Time to First Byte (TTFB)
- Progressive page loading with Suspense boundaries
- Better perceived performance
See the Streaming Server Rendering guide for usage details.
Important
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).
Renders React Server Component (RSC) payloads in NDJSON format for client-side consumption. Used in conjunction with RSC support to enable:
- Reduced JavaScript bundle sizes
- Server-side data fetching
- Selective client-side hydration
See the React on Rails Pro Configuration for RSC setup.
See the lib/react_on_rails/helper.rb source.