|  | 
| 8 | 8 | 
 | 
| 9 | 9 | ## Using Turbo | 
| 10 | 10 | 
 | 
| 11 |  | -To configure Turbo the following option can be set: | 
| 12 |  | -`ReactOnRails.setOptions({ turbo: true })` | 
|  | 11 | +Turbo is the modern replacement for Turbolinks, providing fast navigation through your Rails app without full page reloads. | 
| 13 | 12 | 
 | 
| 14 |  | -Turbo is not auto-detected like older Turbolinks. | 
|  | 13 | +### Basic Setup (Free) | 
| 15 | 14 | 
 | 
| 16 |  | -_TODO: Walk through code changes in PR 1620._ | 
|  | 15 | +**1. Install Turbo** | 
|  | 16 | + | 
|  | 17 | +Add the Turbo Rails gem and JavaScript package: | 
|  | 18 | + | 
|  | 19 | +```bash | 
|  | 20 | +# Gemfile | 
|  | 21 | +gem "turbo-rails" | 
|  | 22 | + | 
|  | 23 | +# JavaScript | 
|  | 24 | +yarn add @hotwired/turbo-rails | 
|  | 25 | +``` | 
|  | 26 | + | 
|  | 27 | +**2. Enable Turbo in React on Rails** | 
|  | 28 | + | 
|  | 29 | +Import Turbo and configure React on Rails to work with it: | 
|  | 30 | + | 
|  | 31 | +```js | 
|  | 32 | +// app/javascript/packs/application.js | 
|  | 33 | +import '@hotwired/turbo-rails'; | 
|  | 34 | + | 
|  | 35 | +ReactOnRails.setOptions({ | 
|  | 36 | +  turbo: true, // Enable Turbo support (not auto-detected) | 
|  | 37 | +}); | 
|  | 38 | +``` | 
|  | 39 | + | 
|  | 40 | +**3. Use Turbo Frames** (works out of the box) | 
|  | 41 | + | 
|  | 42 | +Turbo Frames work with React components without any special configuration: | 
|  | 43 | + | 
|  | 44 | +```erb | 
|  | 45 | +<%# app/views/items/index.html.erb %> | 
|  | 46 | +<%= turbo_frame_tag 'item-list' do %> | 
|  | 47 | +  <%= react_component("ItemList", props: @items) %> | 
|  | 48 | +<% end %> | 
|  | 49 | +
 | 
|  | 50 | +<%# Clicking a link that responds with another turbo_frame_tag will update just that frame %> | 
|  | 51 | +``` | 
|  | 52 | + | 
|  | 53 | +### Turbo Streams (Requires React on Rails Pro) | 
|  | 54 | + | 
|  | 55 | +> **⚡️ React on Rails Pro Feature** | 
|  | 56 | +> | 
|  | 57 | +> Turbo Streams require the `immediate_hydration: true` option, which is a [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/) licensed feature. | 
|  | 58 | +
 | 
|  | 59 | +**Why Turbo Streams Need Special Handling:** | 
|  | 60 | + | 
|  | 61 | +Unlike Turbo Frames, Turbo Streams don't dispatch the normal `turbo:render` events that React on Rails uses to hydrate components. Instead, they directly manipulate the DOM. The `immediate_hydration` option tells React on Rails to hydrate the component immediately when it's inserted into the DOM, without waiting for page load events. | 
|  | 62 | + | 
|  | 63 | +**Example: Create a Turbo Stream Response** | 
|  | 64 | + | 
|  | 65 | +```erb | 
|  | 66 | +<%# app/views/items/index.html.erb - Initial page with frame %> | 
|  | 67 | +<%= turbo_frame_tag 'item-list' do %> | 
|  | 68 | +  <%= button_to "Load Items", items_path, method: :post %> | 
|  | 69 | +<% end %> | 
|  | 70 | +``` | 
|  | 71 | + | 
|  | 72 | +```erb | 
|  | 73 | +<%# app/views/items/create.turbo_stream.erb - Turbo Stream response %> | 
|  | 74 | +<%= turbo_stream.update 'item-list' do %> | 
|  | 75 | +  <%= react_component("ItemList", | 
|  | 76 | +                      props: @items, | 
|  | 77 | +                      immediate_hydration: true) %> | 
|  | 78 | +<% end %> | 
|  | 79 | +``` | 
|  | 80 | + | 
|  | 81 | +**What Happens:** | 
|  | 82 | + | 
|  | 83 | +1. User clicks "Load Items" button | 
|  | 84 | +2. Rails responds with `create.turbo_stream.erb` | 
|  | 85 | +3. Turbo Stream updates the `item-list` frame with the new React component | 
|  | 86 | +4. `immediate_hydration: true` ensures the component hydrates immediately | 
|  | 87 | + | 
|  | 88 | +**Learn More:** | 
|  | 89 | + | 
|  | 90 | +- See [v16.0 Release Notes](../upgrading/release-notes/16.0.0.md#enhanced-script-loading-strategies) for full `immediate_hydration` documentation | 
|  | 91 | +- See [Streaming Server Rendering](./streaming-server-rendering.md) for another Pro use case | 
|  | 92 | +- Working example in codebase: `spec/dummy/app/views/pages/turbo_stream_send_hello_world.turbo_stream.erb` | 
|  | 93 | +- Contact [justin@shakacode.com](mailto:justin@shakacode.com) for React on Rails Pro licensing | 
|  | 94 | + | 
|  | 95 | +**Migration Note:** If you're referencing [PR #1620](https://github.com/shakacode/react_on_rails/pull/1620) discussions, note that `force_load` was renamed to `immediate_hydration` in v16.0. | 
| 17 | 96 | 
 | 
| 18 | 97 | ## Legacy Turbolinks Support | 
| 19 | 98 | 
 | 
| @@ -96,8 +175,17 @@ document.addEventListener('turbolinks:load', function () { | 
| 96 | 175 | 
 | 
| 97 | 176 | React on Rails 15 fixes both issues, so if you still have the listener it can be removed (and should be as `reactOnRailsPageLoaded()` is now async). | 
| 98 | 177 | 
 | 
| 99 |  | -> [!WARNING] | 
| 100 |  | -> Do not use `immediate_hydration: false` (React on Rails Pro licensed feature) with Turbolinks if you have async scripts. | 
|  | 178 | +> [!WARNING] > **Async Scripts with Turbolinks Require Pro Feature** | 
|  | 179 | +> | 
|  | 180 | +> If you use async script loading with Turbolinks, you must enable `immediate_hydration: true` to prevent race conditions. This is a React on Rails Pro feature. | 
|  | 181 | +> | 
|  | 182 | +> Without `immediate_hydration: true`, async scripts may not be ready when Turbolinks fires navigation events, causing components to fail hydration. | 
|  | 183 | +> | 
|  | 184 | +> **Alternatives:** | 
|  | 185 | +> | 
|  | 186 | +> - Use `defer` instead of `async` (waits for full page load before hydration) | 
|  | 187 | +> - Upgrade to modern Turbo (recommended) | 
|  | 188 | +> - Use React on Rails Pro for `immediate_hydration: true` | 
| 101 | 189 | 
 | 
| 102 | 190 | ### Turbolinks 5 Specific Information | 
| 103 | 191 | 
 | 
|  | 
0 commit comments