The backend had been broadcasting events for months. Order created, order status changed, SMS received — each one firing on a private tenant channel through Pusher. The events were implemented, the channel authorization was written, the infrastructure was paid for. Nobody was listening.
The frontend needed three things: an Echo bootstrap, a channel auth mechanism that works with Supabase JWT, and event listeners.
Laravel's default Broadcast::routes() registers its auth endpoint with the web guard, which doesn't work when authentication runs through Supabase JWT middleware. A custom POST /api/broadcasting/auth route, wrapped in the Supabase auth middleware, calls Broadcast::auth() after the JWT middleware has set Auth::user(). The Echo config uses a custom authorizer that sends the Supabase JWT as a Bearer token.
A usePusher composable manages the tenant's private channel subscription — auto-subscribes on mount, re-subscribes when the tenant changes, cleans up on unmount. Three event listeners wired into the app layout: a toast for new orders, a toast for status changes, a toast for incoming SMS with the customer name and message preview.
The application went from checking for updates on page refresh to receiving them the moment they happen. An order created by the widget appears in the operator's dashboard before they finish their current phone call. A customer's SMS reply appears as a toast while the operator is editing a different order. Real-time changes the relationship between the user and their data from pull to push.