← Use cases

Filament panels with live notifications and edit locks

One command: a bell that updates at once, who’s here, edit locks, and tables that refresh themselves.

Filament panels are where teams spend their day: orders, tickets, content and approvals. By default the panel finds out about changes by polling, so the notification bell lags up to 30 seconds, tables go stale, and two people can save over each other's work. Filament already speaks to any Pusher-compatible service through Laravel Echo, and our hibira-io/filament plugin turns that on with one command, for Filament 3, 4 and 5. There is no WebSocket server to run and nothing to build with npm.

What your team gets

  • A notification bell that updates the moment a notification is stored, for every notification your app already sends.
  • Avatars of who else is on the same page, and edit locks so only one person edits a record at a time.
  • Tables, relation managers and record pages that update themselves when something changes, in the panel, a queued job or an API call.
  • Progress bars for imports and exports, and a team chat page.
An edit lock: Mei is editing the article, so saving is off for everyone else, with an Ask to edit button
An edit lock: Mei is editing the article, so saving is off for everyone else, with an Ask to edit button

Built with

  • Laravel Broadcasting with the hibira connection from hibira-io/laravel.
  • Filament's own Laravel Echo, pointed at Hibira by the plugin.
  • Private channels for notifications, tables and records; presence channels for who's here and edit locks.
  • The Channels HTTP API, which the server uses to check who is still on a record before moving its lock.
Laravelsaves, notifications, imports
one message per request
Hibiraws.hibira.io
WebSocket
Filament panelbell, tables, record pages

Who may listen

Filament panelPOST /broadcasting/auth
canAccessPanel()
Laravelchannel rules
signature
Hibira
Your app sends changes to Hibira when a request or job ends; the panels that have the page open update at once

Step 1: install with one command

composer require hibira-io/filament
php artisan hibira:filament

The command adds the settings to .env and asks for your app ID, key and secret, turns on the broadcasting auth route, creates the notifications table, and adds the plugin to your panel providers. Then it checks the connection and each panel. Run it again at any time; it only changes what is missing. Add your site's address to Allowed origins on your app page so browsers can connect.

Step 2: notifications that arrive at once

Nothing to change in your code. Every database notification updates the bell as soon as it is stored, including ones sent without isEventDispatched: true:

Notification::make()
    ->title('Order #1024 shipped')
    ->success()
    ->sendToDatabase($user);

Filament stores its notifications from the queue, so keep php artisan queue:work running, or use QUEUE_CONNECTION=sync while developing.

Step 3: who's here and edit locks

hibira:filament turns on the avatars. For edit locks, add one trait to an edit page:

class EditPost extends EditRecord
{
    use InteractsWithHibiraLock;

    protected static string $resource = PostResource::class;
}

The first person to open the record holds the lock; others can look and ask for it. When the holder leaves, the next person takes it within seconds, with no heartbeat polling.

The holder gets the request and can save before handing over
The holder gets the request and can save before handing over

Step 4: live tables and record pages

With liveTables() and liveRecords() on, tables and record pages update for everyone who has them open. A burst of changes, such as an import of a thousand rows, is sent once per request or queued job, not once per row. Edit pages say who changed the record and load only the changed fields, so unsaved edits stay.

After a mass update through the query builder, which fires no model events, mark the table yourself:

Order::query()->where('paid', false)->update(['status' => 'cancelled']);

app(\Hibira\Filament\LiveTables::class)->touch(Order::class);
Ken saved the post while Mei was editing it: the page says so, and Load changes brings in only his fields
Ken saved the post while Mei was editing it: the page says so, and Load changes brings in only his fields

Step 5: more for your panel

Importing 1,000 rows: the card moves with each chunk while the table fills in
Importing 1,000 rows: the card moves with each chunk while the table fills in

Coming from Reverb or polling

If your panel already uses Echo with Reverb or Pusher, the plugin replaces the filament.broadcasting.echo settings for the panel it is on, and your own events and channel rules keep working. If the panel polls today, ->databaseNotifications() turns polling off; pass polling: '60s' to keep it as a fallback. The migration page lists what to check.

Tips

  • Create one app per environment (local, staging, production) so test events never reach real users.
  • Panels that sign in with their own guard need the broadcasting routes registered with it; hibira:filament tells you when.
  • A burst of changes goes out as one message per request or queued job, which keeps usage low; see pricing for what each plan includes.