Real-time Notifications with Broadcasting in Laravel
Master real-time notifications with Laravel broadcasting. Learn to configure WebSockets, create broadcast events, and sync your UI using Laravel Echo.
Previously in this course, we explored Introduction to Laravel Events and Listeners for Clean Code to decouple our business logic. In this lesson, we are taking that concept a step further by pushing those events directly to the client's browser, enabling real-time UI updates for our project board.
Understanding Real-time Broadcasting
In a standard HTTP request-response cycle, the client must poll the server to see if anything has changed. This is inefficient. With websockets and broadcasting, the server pushes data to the client the moment an event occurs.
Laravel handles this complexity by providing an abstraction layer. You trigger an event in your backend, and Laravel’s broadcasting system sends it to a driver (like Pusher or a local Soketi/Reverb server), which then pushes it to the connected client.
Configuring Broadcasting
First, ensure your broadcasting.php config file is set up. For local development, many developers prefer Laravel Reverb, which is a first-party, high-performance WebSocket server.
- Install Reverb:
php artisan install:broadcasting - Update your
.envfile to useBROADCAST_CONNECTION=reverb. - Start the server:
php artisan reverb:start.
This creates a persistent connection between your client and server, allowing for near-instant communication.
Creating Broadcast Events
To make an event broadcastable, it must implement the ShouldBroadcast interface. Let’s evolve our TaskCreated event from our project board project.
PHPnamespace App\Events; use App\Models\Task; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Queue\SerializesModels; class TaskCreated implements ShouldBroadcast { use InteractsWithSockets, SerializesModels; public function __construct(public Task $task) {} public function broadcastOn(): Channel { #6A9955">// Broadcast to a private channel scoped to the project return new \Illuminate\Broadcasting\PrivateChannel('project.' . $this->task->project_id); } }
By implementing ShouldBroadcast, Laravel will automatically queue this event. When the event is dispatched, it serializes the Task model and sends it to the configured WebSocket driver.
Implementing Client-Side Listeners
Now that the backend is broadcasting, we need the frontend to listen. We use Laravel Echo, the companion library for interacting with these broadcasts.
Assuming you have Laravel Echo installed (via npm install laravel-echo pusher-js), add this to your JavaScript entry point:
JAVASCRIPTimport Echo from CE9178">'laravel-echo'; import Pusher from CE9178">'pusher-js'; window.Echo = new Echo({ broadcaster: CE9178">'reverb', key: import.meta.env.VITE_REVERB_APP_KEY, wsHost: import.meta.env.VITE_REVERB_HOST, forceTLS: false, }); // Listening for the event window.Echo.private(CE9178">`project.${projectId}`) .listen(CE9178">'TaskCreated', (e) => { console.log(CE9178">'New task received:', e.task); // Update your UI state here(e.g., append to the task list) });
Hands-on Exercise
- Modify your existing
TaskServicefrom Service-Oriented Task Management: Building Robust Business Workflows to dispatch theTaskCreatedevent after a task is saved. - Open your browser console and the terminal running
php artisan reverb:start. - Trigger a task creation through your API and verify that the JSON payload appears in the client-side console.
Common Pitfalls
- Forgetting to dispatch the event: Broadcasting only works if the event is actually dispatched. Ensure you are calling
event(new TaskCreated($task))in your service layer. - Authorization Failures: If you are using
PrivateChannel, yourroutes/channels.phpmust define who is allowed to listen. If you don't returntruein the callback, the client will never connect. - Queue Driver: Broadcasting relies on the queue system. If your
QUEUE_CONNECTIONis set tosync, your broadcast might feel slow or fail if the WebSocket server isn't responsive. Useredisordatabasefor production-like behavior.
Recap
We've bridged the gap between our backend events and the client UI. By configuring Reverb, implementing ShouldBroadcast on our events, and using Laravel Echo to listen on private channels, we have enabled true real-time capabilities in our project board. This eliminates the need for manual page refreshes and creates a polished, reactive experience for our users.
Up next: We will explore Job Chaining and Batching to handle complex, multi-step background processes efficiently.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.