Mastering Turbo Streams in Rails 8
Seamless Dynamic Updates with Turbo Frames, AJAX, and Stream Responses# Rails8Series — Episode 6
These examples demonstrate how to use Turbo Streams in Rails 8 to handle dynamic updates of specific parts of the view. Here’s an explanation of each approach:


0. Prelude:
<%= turbo_frame_tag "hot_table" do %>
<%= render partial: 'shared/hot_table', locals: { data: @data } %>
<% end %>
Why it's "Hot":
- Dynamic Updates: Turbo Frames keep your UI fresh without full-page reloads.
- Reusable Partial: The
shared/hot_table
partial centralizes logic for easy updates. - Seamless Integration: Use your controller to pass
@data
and let the magic happen!
Controller Example:
def show_hot_table
@data = YourModel.recent_data
end
Add some styling flair and let your table sizzle with interactivity! 🔥
1.Turbo Stream Direct Replacement
Code:
<turbo-stream action="replace" target="<%= dom_id frame %>">
<template>
<%= render 'model', frame: frame %>
</template>
</turbo-stream>
Explanation:
This is a direct Turbo Stream action.
action="replace"
: Replaces the content of the DOM element identified by the target.
target="<%= dom_id frame %>"
: Specifies the DOM element (usually identified by an ID or a CSS selector) to replace.
<template>
: Contains the HTML to render inside the target element.
Usage:
This is often used in server-side rendered responses for updating specific parts of a page dynamically without refreshing the entire page. It requires Turbo Streams enabled in Rails.
2. Turbo Frame for Button Interaction
Code Overview:
View:
<%= turbo_frame_tag “test_button” do %>
tag
<% end %>
<%= link_to admin_test_button_path, class: "btn btn-light", data: { turbo_frame: 'test_button', turbo_prefetch: false } do %>
<i class="ph-file-pdf me-2"></i>
turbo_frame_tag button
<% end %>
Controller:
def test_button
@tft = 'Turbo Frame for Button'
end
View (After Response):
<%= turbo_frame_tag "test_button" do %>
<%= @tft %>
<% end %>
Explanation:
Turbo Frame Tag: Defines a frame ("test_button"
) that will be dynamically updated.
link_to
with data-turbo-frame
: Specifies the Turbo Frame (test_button
) to target for the update.
Controller Action: Renders the view or partial inside the Turbo Frame when the link is clicked.
Dynamic Update: The content inside the frame gets replaced without reloading the whole page.
Usage:
Best for single-click actions like updating a part of the page or triggering a dynamic update from the controller.
3. Turbo with Respond
Code Overview:
View:
<%= turbo_frame_tag “teste_respond” do %>
tag
<% end %>
<%= link_to admin_test_respond_path, class: "btn btn-light", data: { turbo_stream: true, turbo_prefetch: false } do %>
<i class="ph-file-pdf me-2"></i>
turbo_frame_tag respond
<% end %>
Controller:
def test_respond
respond_to do |format|
format.turbo_stream {
render turbo_stream: turbo_stream.replace('test_respond', partial: 'test_respond')
}
end
end
Partial:
<%= turbo_frame_tag "test_respond" do %>
turbo with respond
<% end %>
Explanation:
Turbo Stream Response: The respond_to
block allows the controller to send a Turbo Stream response instead of HTML.
turbo_stream.replace
: Replaces the content inside the "test_respond"
frame with the specified partial.
Partial Rendered Inside Turbo Frame: Ensures modularity and clean updates.
Usage:
Ideal for cases where multiple response formats are supported, but you want to prioritize Turbo Stream for seamless updates.
4. Turbo with AJAX
Code Overview:
View:
<%= turbo_frame_tag "test_ajax" do %>
ttt
<% end %>
<script>
function makeAjaxRequest() {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/test_ajax', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var turboFrame = document.getElementById('test_ajax');
if (turboFrame) {
turboFrame.innerHTML = xhr.responseText;
}
}
};
xhr.send();
}
var interval = 5000; // 5 seconds
setInterval(makeAjaxRequest, interval);
</script>
Controller:
def test_ajax
respond_to do |format|
format.turbo_stream do
render turbo_stream: [
turbo_stream.replace('test_ajax', partial: 'test_ajax')
]
end
end
end
Partial:
<%= turbo_frame_tag “test_ajax” do %>
turbo with ajax
<% end %>
Explanation:
AJAX Polling: A JavaScript function (makeAjaxRequest
) sends a GET request every 5 seconds to the server endpoint (/path/to/test_ajax
).
Turbo Stream Response: The server responds with a Turbo Stream update that replaces the frame’s content.
Dynamic Updates: The page updates asynchronously with new content from the server.
Usage:
Useful for real-time updates or polling mechanisms where the content changes frequently.

Summarizing:
The piece of code provided is often referred to as a server-side rendered HTML snippet with embedded JavaScript. Here’s a more detailed breakdown of its components:
- Turbo Frame (Rails ERB):
The<%= turbo_frame_tag "test_ajax" do %>
block is specific to Rails and Turbo. It creates a Turbo Frame, allowing dynamic partial replacements without a full page reload. - Embedded JavaScript:
The<script>
block contains client-side JavaScript that makes an AJAX request to the server to fetch updated content for the Turbo Frame.
Common Names:
- Rails View with Embedded JavaScript
- Turbo Frame with AJAX
- Server-Side Rendering with JavaScript Enhancements
In simpler terms, it’s a combination of Rails Turbo Frame and AJAX-powered dynamic content loading.
Thank You Pedro Henrique!
I appreciate you taking the time to explore this guide. If you found it helpful or insightful, I’d be thrilled if you could visit my other articles and show your support with an applause! Your feedback means the world to me and motivates me to create even better content.
Feel free to share your thoughts or ask questions — I’d love to hear from you! 😊
Credits & References
Based on: Pedro Henrique da Silva Coelho — Desenv SEFIN/RO
Related Posts — Rails8Series
0 # Rails8Series — Managing Rails Versions — How to Handle Accidental Upgrades and Revert to an Older Version
1 # Rails8Series — Building a Rails 8 App from Scratch — A Modern Developer’s Foundation
2 # Rails8Series — Mastering Import Maps in Rails 8 — A Step-by-Step Guide to Efficient JavaScript Management
3 # Rails8Series — Frequently Asked Questions & Answers — 4 Essential Questions Answered!
4 # Rails8Series — Understanding params.expect
— A simplified explanation and code examples
5 # Rails8Series — Initialization in Turbo Streams — Quick Note On Using Rails 8 bin/dev
Command For development
6 # Rails8Series —Mastering Turbo Streams in Rails 8 — Seamless Dynamic Updates with Turbo Frames, AJAX, and Stream Responses# Rails8Seriest (this one)
7 # Rails8Series — Mastering Enums in Rails — A Practical Guide to Simplify and Enhance Your ActiveRecord Models
More Related Posts — HotwireSeries
#Episode — HotwireSeries — Intro — Hotwire Demo — What is the purpose of Hotwire in Rails 7?
1#Episode — HotwireSeries — Turbo Frame — Decomposes Pages Into Independent Contexts.
2#Episode — HotwireSeries — Turbo Stream — Pushing HTML Updates To The Client Using WebSockets.
3#Episode — HotwireSeries — Stimulus — A lightweight JavaScript Framework.
turbo-todos App
Turbo Todos is a simple To-Do List application built with Rails 8 and Tailwind CSS. This app demonstrates the use of Turbo Streams for dynamic, real-time updates without requiring full-page reloads.