developing-with-turbo-streams

4
0
Source

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

Installs 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

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.

643969

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.

591705

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

318399

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.

340397

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.

452339

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.

304231

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.