У матеріалі розбирається підхід автора Paul Redmond до того, як зробити сторінку замовлення в Laravel + Inertia такою, що оновлюється в реальному часі через Laravel Reverb. Ключова ідея — використати Inertia live props і події трансляції, щоб усі відкриті вкладки з конкретним замовленням автоматично бачили зміну статусу.
1. Коли потрібні live props і що вони роблять
З виходом Inertia.js 3.11 зʼявилися live props — спеціальні props, які Inertia оновлює при надходженні подій від сервера. Сторінка сама підписується на канал трансляції, а коли приходить подія — робить частковий reload тільки тих props, які позначені як live.
Автор демонструє це на кейсі статусу замовлення: як тільки замовлення переходить у стан «shipped», усі користувачі, що дивляться сторінку цього замовлення, бачать новий статус без перезавантаження сторінки.
Для прикладу потрібні такі версії пакетів:
inertia-laravelвід 3.7@inertiajs/vue3від 3.11 (або відповідні пакети для React/Svelte)
composer require inertiajs/inertia-laravel:^3.7
npm install @inertiajs/vue3@^3.11
Якщо ви використовуєте React або Svelte, замініть Vue-пакет на @inertiajs/react або @inertiajs/svelte.
2. Налаштування трансляцій: Reverb і Echo
Щоб live props отримували оновлення, потрібна система трансляцій Laravel. Автор використовує вбудований сервер Laravel Reverb разом з Echo.
Laravel має інсталятор для broadcasting, який одразу готує Reverb:
php artisan install:broadcasting --reverb
Ця команда:
- встановлює Reverb
- додає змінні
REVERB_*іVITE_REVERB_*в.env - створює
routes/channels.phpдля каналів трансляції - для Vue/React проектів — встановлює відповідний Echo-пакет (
@laravel/echo-vueабо@laravel/echo-react) і вставляє викликconfigureEcho()вresources/js/app.tsабоapp.tsx
import { configureEcho } from '@laravel/echo-vue'
configureEcho({
broadcaster: 'reverb',
})
Для Svelte інсталятор Echo не налаштовує, тому там знадобиться вручну додати @laravel/echo-svelte і виклик configureEcho() з такими ж опціями.
3. Подія трансляції для оновлення замовлення
Щоб Inertia знала, з якого каналу слухати live prop, потрібна подія, яка реалізує ShouldBroadcast. Автор створює подію OrderUpdated:
php artisan make:event OrderUpdated
У тілі події важливі два моменти:
- вона приймає модель
Order - визначає приватний канал, на який транслюється оновлення конкретного замовлення
Таким чином, кожне замовлення слухається на своєму каналі orders.{id}. Оскільки це PrivateChannel, потрібне правило авторизації в routes/channels.php, щоб сторонні користувачі не могли підписатись на чужі замовлення. Автор обмежує доступ власником замовлення:
Ця умова перевіряє, що $user->id збігається з $order->user_id. Без такої перевірки приватні канали не будуть працювати, або, в разі занадто слабких правил, виникне витік даних.
4. Маркуємо prop як live у контролері
Далі автор показує, як перетворити звичайний Inertia-prop order на live prop. Це робиться в контролері через Inertia::live():
Ключові деталі цієї конфігурації:
- Значення через замикання. Функція
fn () => $order->fresh()повертає завжди актуальний стан замовлення. Inertia викликає цю функцію при першому рендері сторінки і щоразу, коли потрібно перезавантажити live prop. - Параметр
on:отримує екземпляр події трансляціїnew OrderUpdated($order). Створення події тут нічого не транслює — Inertia лише викликає в неїbroadcastOn(), щоб дізнатись, на який канал підписуватися.
В результаті, кожна сторінка, яка рендерить Orders/Show з таким live prop, буде:
- підписана на
orders.{order-id} - отримувати події
OrderUpdated - робити частковий reload тільки для props, позначених як live
5. Підключення клієнта Inertia до Echo
Щоб live props реально реагували на події, Inertia на фронтенді має отримати транспорт echo(). У Vue-проєкті автор підключає його в resources/js/app.ts після виклику configureEcho():
Пара моментів, на які варто звернути увагу:
- пакет
@inertiajs/vue3/echoнадає функціюecho(), яку і потрібно передати в опціюliveпри створенні Inertia-додатку - додаткового коду у сторінковому компоненті для props не потрібно — достатньо того, що prop позначений як live у контролері, а клієнтське
live: echo()налаштоване
При завантаженні сторінки Inertia сама:
- зʼєднується з Reverb через Echo
- підписується на канали, описані у live props
- оновлює дані при надходженні подій
6. Де й як транслювати подію оновлення
Коли користувач або бекграунд-процес змінює статус замовлення, потрібно відправити подію OrderUpdated. Автор наводить базовий приклад:
У цьому випадку всі вкладки, де відкрита сторінка поточного замовлення, отримають подію, і Inertia зробить partial reload prop order. Але вкладка користувача, який зробив зміну, зазвичай уже бачить нові дані у відповіді на свій запит. Щоб не дублювати оновлення для цього клієнта, можна скористатися toOthers():
Це викликає трансляцію на Reverb всім підписникам каналу, крім клієнта з відповідним socket ID. Inertia автоматично передає socket ID у заголовку X-Socket-Id з кожним запитом до того ж домену, і Laravel Broadcasting використовує його, щоб визначити, кого вважати «тим самим» клієнтом.
7. Запуск Reverb і черги подій
Події з інтерфейсом ShouldBroadcast за замовчуванням відправляються в чергу. Тому, окрім налаштованого Reverb-сервера, потрібен ще queue worker.
Для запуску Reverb автор використовує:
У нових додатках Laravel composer run dev зазвичай уже запускає queue:work. Якщо ж ви не користуєтеся цим скриптом, worker треба запустити самостійно:
Якщо є потреба виконувати трансляцію синхронно, в ході HTTP-запиту, а не через чергу, можна реалізувати ShouldBroadcastNow замість ShouldBroadcast. Це корисно у середовищах без налаштованих черг, але варто памʼятати про потенційне збільшення часу відповіді.
8. Індикація перезавантаження props на фронтенді
Щоб користувач бачив, що live prop зараз оновлюється, Inertia пропонує хук useProp(). Автор ілюструє це на прикладі Vue-компонента сторінки замовлення:
Тут:
defineProps(['order'])оголошує звичайний prop з даними замовленняconst { loading } = useProp('order')повертає реактивний прапорецьloadingсаме для цього prop- у шаблоні умовно виводиться повідомлення «Updating...», коли
loadingістинний
Отже, користувач бачить як сам статус, так і коротке повідомлення про те, що значення зараз оновлюється в реальному часі.
9. Зменшення навантаження: передача значення в події
За замовчуванням кожна подія, повʼязана з live prop, спричиняє окремий HTTP-запит до сервера для кожної відкритої сторінки. Якщо сторінок багато, це стає відчутним навантаженням. Автор пропонує оптимізацію: приєднати до події готові дані для props через broadcastWith().
У прикладі дані замовлення готуються через OrderResource, а потім пропускаються через Inertia::broadcastProps():
Особливості такого підходу:
- дані для props прилітають разом з подією Reverb, Inertia просто оновлює стан на клієнті без додаткового запиту до серверного контролера
Inertia::broadcastProps()формує payload у тому ж форматі, в якому props приходять при звичайному рендері- оновлюються тільки ті props, які явно слухають дану подію — подія не може зробити «приховане» оновлення якихось сторонніх даних на сторінці
Обмеження цього методу важливе: усі користувачі, які слухають канал, отримують однаковий payload. Тому автор застерігає — не застосовувати таке оновлення для значень, які залежать від конкретного користувача (наприклад, індивідуальних прав або приватних даних, відмінних для кожного слухача).
10. Контроль частоти оновлень live props
Ще одна потенційна проблема — надто часті оновлення. Inertia за замовчуванням застосовує ліміт: кожен live prop перезавантажується не частіше ніж раз на секунду. Для джерел з інтенсивними подіями (лог активності, показники в реальному часі) автор показує, як явно задати більший інтервал.
У прикладі prop activity оновлюється не частіше, ніж раз на 5 секунд (5000 мс):
Тут:
throttle: 5000задає мінімальний інтервал між перезавантаженнями для цього конкретного live prop- значення береться з
$order->activity, але також слухає подіюActivityLogged
Також Inertia ставить перезавантаження на паузу, коли вкладка браузера прихована, і застосовує їх, коли користувач повертається. Водночас значення, які приходять безпосередньо в payload через broadcastProps(), оновлюються незалежно від того, активна вкладка чи ні.
11. Підсумкова схема для сторінки замовлення
У підході, який описує автор, сторінка замовлення з live props працює так:
- на бекенді налаштовані Reverb, Echo і черги
- подія
OrderUpdatedтранслюється в приватний каналorders.{id}, доступний лише власнику замовлення - контролер повертає сторінку з live prop
order, який знає про цей канал - на фронтенді Inertia ініціалізується з
live: echo(), автоматично підписується на канал і оновлює prop при надходженні події - опційно: подія містить готові дані для props через
broadcastWith(), а частота оновлень обмежується параметромthrottle
У результаті будь-який користувач, що має право дивитися замовлення, бачить зміну статусу в реальному часі без написання власної логіки підписки на канали в компонентах і без повного перезавантаження сторінки.
Джерело: Paul Redmond — Laravel News