Inertia live props, added in v3.11.0, keep a page current when data changes on the server. Mark a prop as live, broadcast an event, and every page showing that prop reloads it.
Let's demonstrate how live props work by implementing an order status page with Laravel Reverb, so anyone viewing an order sees the new status when it ships. You'll need inertia-laravel 3.7 and Inertia.js 3.11 or later:
composer require inertiajs/inertia-laravel:^3.7 npm install @inertiajs/vue3@^3.11
For React or Svelte, install @inertiajs/react or @inertiajs/svelte instead.
#Install Reverb and Echo
Run the broadcasting installer with the --reverb option:
php artisan install:broadcasting --reverb
This installs Reverb, adds the REVERB_* and VITE_REVERB_* keys to .env, and creates routes/channels.php. For Vue and React apps, it also installs the matching Echo package (@laravel/echo-vue or @laravel/echo-react) and adds a configureEcho() call to resources/js/app.ts or app.tsx:
import { configureEcho } from '@laravel/echo-vue' configureEcho({ broadcaster: 'reverb', })
The installer only detects Vue and React, so in a Svelte app you'll need to install @laravel/echo-svelte and add the same configureEcho() call yourself.
#Create the Broadcast Event
Next, create an event to represent the change:
php artisan make:event OrderUpdated
Have it implement ShouldBroadcast and return the channel it should broadcast on:
namespace App\Events; use App\Models\Order; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class OrderUpdated implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public function __construct(public Order $order) {} public function broadcastOn(): PrivateChannel { return new PrivateChannel("orders.{$this->order->id}"); } }
Private channels need an authorization rule in routes/channels.php. This one lets only the order's owner listen:
use App\Models\Order; use Illuminate\Support\Facades\Broadcast; Broadcast::channel('orders.{order}', function ($user, Order $order) { return $user->id === $order->user_id; });
#Mark the Prop as Live
In the controller, wrap the prop in Inertia::live() and pass it an instance of the event:
use App\Events\OrderUpdated; use App\Models\Order; use Inertia\Inertia; public function show(Order $order) { return Inertia::render('Orders/Show', [ 'order' => Inertia::live(fn () => $order->fresh(), on: new OrderUpdated($order)), ]); }
Creating the event here doesn't broadcast it. Inertia calls its broadcastOn() method to find the channel, then sends the channel and event name to the page.
Pass the value as a closure, since Inertia runs it on the first render and again each time the prop reloads.
#Connect the Client
On the frontend, pass the echo() transport to createInertiaApp() in resources/js/app.ts, below the configureEcho() call the installer added:
import { createInertiaApp } from '@inertiajs/vue3' import { echo } from '@inertiajs/vue3/echo' import { configureEcho } from '@laravel/echo-vue' configureEcho({ broadcaster: 'reverb', }) createInertiaApp({ // your existing options... live: echo(), })
You don't need to change the page component. It reads the order prop as usual, and Inertia subscribes to the channel when the page loads.
#Broadcast the Event
Dispatch the event wherever the order changes:
$order->update(['status' => 'shipped']); OrderUpdated::dispatch($order);
Every open page showing this order then makes a partial reload for the order prop. The user who made the change usually has the new data from their own response, so you can skip their tab with toOthers():
broadcast(new OrderUpdated($order))->toOthers();
The toOthers() method relies on the socket ID, which Inertia sends in an X-Socket-Id header with each same-origin request.
#Run Reverb and a Queue Worker
Start the Reverb server:
php artisan reverb:start
Events that implement ShouldBroadcast are queued, so you also need a queue worker running. The composer run dev script in new Laravel apps runs one for you. If you aren't using it, start a worker yourself:
php artisan queue:work
To skip the queue and broadcast during the request, implement ShouldBroadcastNow instead.
#Show a Loading State
Use the useProp() hook to show when Inertia is reloading a prop:
<script setup> import { useProp } from '@inertiajs/vue3' defineProps(['order']) const { loading } = useProp('order') </script> <template> <p>Status: {{ order.status }}</p> <span v-if="loading">Updating...</span> </template>
#Send the Value in the Event
Each event sends a request to your server from every page listening for it. With many viewers, you can put the new value in the event payload and skip those requests:
use App\Http\Resources\OrderResource; use Inertia\Inertia; public function broadcastWith(): array { return [ ...Inertia::broadcastProps([ 'order' => OrderResource::make($this->order), ]), ]; }
Inertia only writes props that listen for this event, so a payload can't change a prop the event isn't declared on. Because every user on the channel receives the same payload, don't use this for values that depend on who is viewing the page.
#Throttle Frequent Updates
Inertia reloads each live prop at most once per second by default. For props that change often, set a longer throttle in milliseconds:
'activity' => Inertia::live(fn () => $order->activity, on: new ActivityLogged($order), throttle: 5000),
Inertia also pauses reloads while the browser tab is hidden and runs them when the user returns. Values sent with broadcastProps() are written to the page either way.
Комментарии (0)
Пока нет комментариев — будьте первым.