Skip to content

Commit 1f05e1a

Browse files
ihabadhamclaude
andcommitted
Document Turbo integration and immediate_hydration feature (resolve TODO)
Replace TODO from PR #1620 with comprehensive Turbo documentation covering both free (Turbo Frames) and Pro (Turbo Streams) features. Changes: 1. **New "Using Turbo" Section** - Installation steps (turbo-rails gem + @hotwired/turbo-rails package) - Basic configuration (ReactOnRails.setOptions({ turbo: true })) - Turbo Frames usage (free, works out of the box) - Turbo Streams usage (requires immediate_hydration: true - Pro feature) - Complete working example with turbo_frame_tag and turbo_stream.update - Links to v16.0 release notes, streaming docs, and spec/dummy example 2. **Migration Context** - Note about force_load → immediate_hydration rename in v16.0 - Clear distinction between free vs Pro features - Explanation of WHY Turbo Streams need immediate_hydration (they don't dispatch turbo:render events, directly manipulate DOM) 3. **Improved Async Scripts Warning** - Replaced confusing "Do not use immediate_hydration: false" warning - New clear warning: "Async Scripts with Turbolinks Require Pro Feature" - Explains the race condition problem - Provides three alternatives with behavioral descriptions: * defer (waits for full page load before hydration) * Upgrade to Turbo (recommended) * Use Pro for immediate_hydration: true Technical Context: - PR #1620 (Aug 2024) added force_load for Turbo Streams - PR #1781 (Sep 2025) renamed to immediate_hydration + made Pro-only - Feature still actively used (spec/dummy has working example) - Default immediate_hydration: false causes race conditions with async scripts Resolves TODO on line 16 left by Justin in PR #1620 comments. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 28b8c8f commit 1f05e1a

File tree

1 file changed

+94
-6
lines changed

1 file changed

+94
-6
lines changed

docs/building-features/turbolinks.md

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,91 @@
88

99
## Using Turbo
1010

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.
1312

14-
Turbo is not auto-detected like older Turbolinks.
13+
### Basic Setup (Free)
1514

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.
1796

1897
## Legacy Turbolinks Support
1998

@@ -96,8 +175,17 @@ document.addEventListener('turbolinks:load', function () {
96175

97176
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).
98177

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`
101189
102190
### Turbolinks 5 Specific Information
103191

0 commit comments

Comments
 (0)