What a turbo stream tag actually is
A <turbo-frame> (the last course) waits to be asked: a link or form targets it, and its content swaps. A <turbo-stream> works the other way around. It's a small, self-describing instruction that arrives and acts on its own, whether or not anyone clicked anything on the page it lands in.
Seven verbs, one shape
This app's installed turbo-rails-2.0.23 gem lists the action vocabulary in its own source comments:
There are seven basic actions you can broadcast:
after,append,before,prepend,remove,replace, andupdate.
Each one renders to the same tag shape: an action, a target id, and (except for remove, which only needs the id) a template with HTML inside:
<turbo-stream action="replace" target="clearance_5">
<template>
<div id="clearance_5">Other partial</div>
</template>
</turbo-stream>
replace swaps the whole element. update replaces only its contents. append and prepend add to the end or start of a container. before and after insert a sibling. remove deletes the target. The verbs differ, but the mechanism is the same: find the element with this id and apply one DOM operation to it. Turbo 8.0.23, the version this app ships, also has an eighth action, refresh, which carries no target and no template. Lesson 5 covers it.
Where the tag gets built
You rarely write the raw <turbo-stream> markup by hand. The installed gem ships Turbo::Streams::TagBuilder, available in views and controllers as turbo_stream. Its doc comment shows this shape:
def create
@message = Message.create!(params.require(:message).permit(:content))
respond_to do |format|
format.turbo_stream
format.html { redirect_to messages_url }
end
end
<%# app/views/messages/create.turbo_stream.erb %>
<%= turbo_stream.append "messages", @message %>
<%= turbo_stream.replace "new_message" do %>
<%= render partial: "new_message", locals: { room: @room } %>
<% end %>
format.turbo_stream in the controller, paired with a create.turbo_stream.erb template, is Rails' respond_to doing what it does for format.html and format.json: picking a template based on what the client asked for. This format's template calls turbo_stream.append, .replace and the rest, which build the tag shape from the last section instead of a plain HTML fragment.
Not a request-response frame swap
A turbo frame update (last course) is tied to one navigation: a link or form asks, and a response scoped to that frame answers. A turbo stream tag carries its target id with it, and it doesn't have to come from something the current page asked for. That makes it the right shape for the next lesson: an update that arrives because someone else did something, not because you clicked.
Key takeaways
- This app's installed Turbo gem documents seven basic broadcast actions:
after,append,before,prepend,remove,replaceandupdate. Each renders to the same<turbo-stream action="..." target="...">shape. turbo_stream, aTurbo::Streams::TagBuilder, builds these tags in Ruby with.replace,.appendand so on, so you don't hand-write the markup.format.turbo_streamin a controller, with a.turbo_stream.erbtemplate, is the samerespond_tomechanism asformat.htmlandformat.json. It just responds with stream tags instead of a page.- Unlike a turbo frame, a stream tag isn't tied to answering one request. It carries its own target id and can arrive whether or not the page asked for anything.
Keep going with lesson 2
Subscribing with turbo_stream_from
Shows how turbo_stream_from opens a WebSocket subscription to one named stream on the public roadmap page.
A free account also gives you the quizzes, your progress and notes, and the discussion.