DE

developing-with-turbo-streams

Implements Turbo Streams for real-time, partial page updates and dynamic content rendering.

Install

mkdir -p .claude/skills/developing-with-turbo-streams && curl -L -o skill.zip "https://agentskills.codes/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

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

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.
250 chars · catalog description✓ has a “when” trigger
Intermediate

Key capabilities

  • Constructs HTTP Turbo Stream response objects
  • Injects HTML snippets using DOM actions
  • Detects Turbo-specific request headers
  • Updates partial components without full page reloads
  • Synthesizes server-side model state into stream actions

How it works

Uses a fluent PHP builder to return standardized Turbo-encoded HTML responses that the browser-side Turbo Drive handles via event listeners.

Inputs & outputs

You give it
Eloquent model, stream action type, or view string
You get back
Turbo Stream HTML fragment

When to use developing-with-turbo-streams

  • Implementing real-time list updates
  • Updating page components without full reloads
  • Managing WebSocket broadcast actions

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

When not to use it

  • Standard non-AJAX full page navigation
  • Client-side heavy applications avoiding server-rendered HTML

Prerequisites

Hotwire/Turbo installed in Laravel

Limitations

  • Requires server-side HTML rendering
  • Limited to eight specific DOM actions

How it compares

Eliminates custom JavaScript boilerplate for common DOM manipulation tasks like appending list items or replacing error blocks.

Compared to similar skills

developing-with-turbo-streams side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
developing-with-turbo-streams (this skill)15moNo flagsIntermediate
laravel-specialist123moNo flagsIntermediate
developing-with-turbo-basics15moNo flagsIntermediate
payment-integration16moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

laravel-specialist

Jeffallan

Use when building Laravel 10+ applications requiring Eloquent ORM, API resources, or queue systems. Invoke for Laravel models, Livewire components, Sanctum authentication, Horizon queues.

1215

developing-with-turbo-basics

hotwired-laravel

Basics of developing with Turbo in web applications. Activate when working on projects that utilize Turbo for enhancing user experience through partial page updates, real-time interactions, and seamless navigation without full page reloads.

13

payment-integration

mrgoonie

Integrate payments with SePay (VietQR), Polar, Stripe, Paddle (MoR subscriptions), Creem.io (licensing). Checkout, webhooks, subscriptions, QR codes, multi-provider orders.

13

developing-with-prism

prism-php

Guide for developing with Prism PHP package - a Laravel package for integrating LLMs. Activate or use when working with Prism features including text generation, structured output, embeddings, image generation, audio processing, streaming, tools/function calling, or any LLM provider integration (OpenAI, Anthropic, Gemini, Mistral, Groq, XAI, DeepSeek, OpenRouter, Ollama, VoyageAI, ElevenLabs). Activate for any Prism-related development tasks.

12

laravel-query-builder

relaticle

Build filtered, sorted, and included API endpoints using spatie/laravel-query-builder. Activates when working with QueryBuilder, AllowedFilter, AllowedSort, AllowedInclude, or when the user mentions query parameters, API filtering, sorting, includes, or spatie/laravel-query-builder.

00

echo-development

WageFolabessy

Develops real-time broadcasting with Laravel Echo. Activates when setting up broadcasting (Reverb, Pusher, Ably); creating ShouldBroadcast events; defining broadcast channels (public, private, presence, encrypted); authorizing channels; configuring Echo; listening for events; implementing client eve

00

Search skills

Search the agent skills registry