developing-with-turbo-streams
Basics of developing with Turbo Streams in web applications. Activate when working on projects that utilize Turbo Streams for enhancing user experience through real-time updates, dynamic content changes, and partial page updates without full reloads.
Install
mkdir -p .claude/skills/developing-with-turbo-streams && curl -L -o skill.zip "https://mcp.directory/api/skills/download/3413" && unzip -o skill.zip -d .claude/skills/developing-with-turbo-streams && rm skill.zipInstalls to .claude/skills/developing-with-turbo-streams
About this skill
Turbo Streams
Turbo Streams let you change any part of the page using eight actions: append, prepend, replace, update, remove, before, after, and refresh. They work as HTTP responses (after form submissions) and as real-time broadcasts over WebSocket.
HTTP Turbo Streams
Detecting Turbo Stream Requests
Check if the request accepts Turbo Stream responses before returning them:
@verbatim
<code-snippet name="Detecting" lang="php"> public function store(Request $request) { $post = Post::create($request->validated());if ($request->wantsTurboStream()) {
return turbo_stream($post);
}
return redirect()->route('posts.show', $post);
} </code-snippet>
@endverbatim
The turbo_stream() Helper
@verbatim
<code-snippet name="turbo_stream helper" lang="php"> // Auto-detect action from context (uses model state: created → append, updated → replace, deleted → remove) return turbo_stream($model); return turbo_stream($model, 'prepend');// Fluent builder (no arguments returns a PendingTurboStreamResponse) return turbo_stream()->append('posts', view('posts._post', ['post' => $post])); return turbo_stream()->prepend('posts', view('posts._post', ['post' => $post])); return turbo_stream()->before(dom_id($post), view('posts._post', ['post' => $newPost])); return turbo_stream()->after(dom_id($post), view('posts._post', ['post' => $newPost])); return turbo_stream()->replace($post, view('posts._post', ['post' => $post])); return turbo_stream()->update($post, view('posts._post', ['post' => $post])); return turbo_stream()->remove($post); return turbo_stream()->refresh(); </code-snippet>
@endverbatim
Targeting Multiple Elements
Use the *All methods or targets() to target multiple elements by CSS selector:
@verbatim
<code-snippet name="Multiple targets" lang="php"> return turbo_stream()->appendAll('.comment', view('comments._comment', ['comment' => $comment])); return turbo_stream()->replaceAll('.notification', view('notifications._notification')); return turbo_stream()->removeAll('.old-item'); </code-snippet>@endverbatim
Morph Method
Use morph() on replace/update to morph content instead of replacing it:
@verbatim
<code-snippet name="Morph" lang="php"> return turbo_stream()->replace($post, view('posts._post', ['post' => $post]))->morph(); </code-snippet>@endverbatim
Combining Multiple Streams
Pass an array or collection to return multiple stream actions in one response:
@verbatim
<code-snippet name="Multiple streams" lang="php"> return turbo_stream([ turbo_stream()->append('posts', view('posts._post', ['post' => $post])), turbo_stream()->update('post_count', view('posts._count', ['count' => Post::count()])), turbo_stream()->remove('empty_state'), ]); </code-snippet>@endverbatim
Turbo Stream Views
Render a full Blade view with the Turbo Stream content type. Useful for complex multi-stream responses:
@verbatim
<code-snippet name="Stream view" lang="php"> return turbo_stream_view('posts.turbo.created', ['post' => $post]); </code-snippet> <code-snippet name="Stream view template" lang="blade"> {{-- resources/views/posts/turbo/created.blade.php --}} <x-turbo::stream action="append" target="posts"> @include('posts._post', ['post' => $post]) </x-turbo::stream><x-turbo::stream action="update" target="post_count"> {{ Post::count() }} posts </x-turbo::stream> </code-snippet>
@endverbatim
The Stream Blade Component
@verbatim
<code-snippet name="Blade component" lang="blade"> {{-- Single target by ID --}} <x-turbo::stream action="append" target="messages"> <div id="message_1">My new message!</div> </x-turbo::stream>{{-- Target by model (auto-generates DOM ID) --}} <x-turbo::stream action="replace" :target="$post"> @include('posts._post', ['post' => $post]) </x-turbo::stream>
{{-- Multiple targets by CSS selector --}} <x-turbo::stream action="remove" targets=".notification" /> </code-snippet>
@endverbatim
Broadcasting (Real-Time Streams)
The Broadcasts Trait
Add the Broadcasts trait to your Eloquent model:
@verbatim
<code-snippet name="Broadcasts trait" lang="php"> use HotwiredLaravel\TurboLaravel\Models\Broadcasts;class Post extends Model { use Broadcasts; } </code-snippet>
@endverbatim
Manual Broadcasting
Call broadcast methods directly on a model instance:
@verbatim
<code-snippet name="Manual broadcasting" lang="php"> $comment->broadcastAppend(); $comment->broadcastPrepend(); $comment->broadcastReplace(); $comment->broadcastUpdate(); $comment->broadcastRemove(); $comment->broadcastBefore('some_target'); $comment->broadcastAfter('some_target'); $comment->broadcastRefresh();// Broadcast only to other users (exclude current user) $comment->broadcastAppend()->toOthers();
// Queue the broadcast for async processing $comment->broadcastAppend()->later(); </code-snippet>
@endverbatim
Directed Broadcasting
Broadcast to a specific model's channel:
@verbatim
<code-snippet name="Directed broadcasting" lang="php"> // Broadcast to the post's channel instead of the comment's own channel $comment->broadcastAppendTo($post); $comment->broadcastPrependTo($post); $comment->broadcastReplaceTo($post); $comment->broadcastUpdateTo($post); $comment->broadcastRemoveTo($post); $comment->broadcastRefreshTo($post); </code-snippet>@endverbatim
Automatic Broadcasting
Enable automatic broadcasts on model lifecycle events:
@verbatim
<code-snippet name="Auto broadcasting" lang="php"> class Comment extends Model { use Broadcasts;// Enable auto-broadcasting (broadcasts on create, update, delete)
protected $broadcasts = true;
// Customize insert action (default is 'append')
protected $broadcasts = ['insertsBy' => 'prepend'];
// Specify which model's channel to broadcast to
protected $broadcastsTo = 'post';
// Or define dynamically
public function broadcastsTo()
{
return $this->post;
}
} </code-snippet>
@endverbatim
Page Refresh Broadcasting
Instead of granular stream actions, broadcast a page refresh signal:
@verbatim
<code-snippet name="Refresh broadcasting" lang="php"> class Post extends Model { use Broadcasts;// Auto-broadcast page refreshes on model changes
protected $broadcastsRefreshes = true;
} </code-snippet>
@endverbatim
This works best with <x-turbo::refreshes-with method="morph" scroll="preserve" /> in the layout.
Listening for Broadcasts
Use the <x-turbo::stream-from> component in your Blade views to subscribe to a channel:
@verbatim
<code-snippet name="Listening" lang="blade"> {{-- Private channel (default) — requires channel auth --}} <x-turbo::stream-from :source="$post" />{{-- Public channel — no auth needed --}} <x-turbo::stream-from :source="$post" type="public" /> </code-snippet>
@endverbatim
Define the channel authorization in routes/channels.php:
@verbatim
<code-snippet name="Channel auth" lang="php"> use App\Models\Post;Broadcast::channel(Post::class, function ($user, Post $post) { return $user->belongsToTeam($post->team); }); </code-snippet>
@endverbatim
Handmade Broadcasts (via Facade)
Use the TurboStream facade for broadcasts not tied to a model:
@verbatim
<code-snippet name="Facade broadcasting" lang="php"> use HotwiredLaravel\TurboLaravel\Facades\TurboStream;TurboStream::broadcastAppend( content: view('notifications._notification', ['notification' => $notification]), target: 'notifications', channel: 'general', );
TurboStream::broadcastRemove(target: 'notification_1', channel: 'general'); TurboStream::broadcastRefresh(channel: 'general'); </code-snippet>
@endverbatim
Broadcasting from Response Builder
Chain broadcastTo() on a Turbo Stream response to also broadcast it:
@verbatim
<code-snippet name="Response broadcasting" lang="php"> turbo_stream() ->append('posts', view('posts._post', ['post' => $post])) ->broadcastTo('general'); </code-snippet>@endverbatim
Global Broadcast Scope
Exclude the current user from all broadcasts in a request:
@verbatim
<code-snippet name="Broadcast to others" lang="php"> use HotwiredLaravel\TurboLaravel\Facades\Turbo;// In a controller or middleware Turbo::broadcastToOthers();
// Anywhere Turbo::broadcastToOthers(function () { // Turbo Streams broadcasted here will not be delivered to the current user... }); </code-snippet>
@endverbatim
More by hotwired-laravel
View all skills by hotwired-laravel →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversThe fullstack MCP framework for developing MCP apps for ChatGPT, Claude, and building MCP servers for AI agents. Connect
Connect StreamerSongList to manage music queues, song requests, play history, and overlays for your Twitch streams seaml
Unlock Twitch analytics and insights with integrated API: channel info, streams, game data, clips, chat, and user profil
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.