Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

"Live" Notification with No Page Reload

Premium
9 min read

Laravel Reverb is one of the newest first-party packages from the Laravel team. With Reverb, we can show page changes in real-time, like this message to users:

That message appears on the screen without refreshing the page or making API calls.

But how does it work? Let's dive into it, with first two practical examples:

  • Sending a global message "The system will go down for maintenance"
  • Sending a private message for a specific user "Your export is finished"

What is Reverb?

Reverb was created to solve the gap between back-end and front-end communications. It's a real-time messaging system that allows us to listen to back-end events and react to them on the front-end.

Here are a few examples of what we can do with Reverb:

  • Build real-time notifications about new messages, comments, reports, or system events.
  • Build real-time chat applications.
  • Build real-time dashboards with live data.
  • Inform users about changes in the system, such as new products, reports, etc.
  • Create presence systems to show who is online and who is not.
  • And many more...

It's a powerful tool that can be used in many different ways. The only limit is our imagination and creativity.


Why Reverb Instead of Periodical Refresh?

But why use Reverb instead of a simple API endpoint? We can call an API endpoint to get the latest data, right? And if we need to wait for something to finish, we can always use Polling, calling the server every minute or so, right?

Well, yes, we can. But we can also use a sword to cut our bread, right? But we don't. We use a knife. Why? Because it's more efficient and easier to use. It's the same with Reverb. Here's why:

With Polling, we send requests to the server every X seconds/minutes to check for new data.

Sounds good. We solved the problem.

But what if we have 1000 users? And then 100 000 users? We will send N (number of users) requests every X seconds. That's a lot of requests!!!

Instead, with Reverb, we can send a single request to the server, and that's it!

It's based on WebSockets. As shown in the image above, it will create a WebSocket connection between the server and the client.

This connection allows our server and client to communicate in real time without sending multiple requests. As long as the connection is open, we can freely send messages/data and avoid creating unnecessary requests that will slow down our server.


Reverb Alternatives?

Before Reverb, we had a few popular alternatives to build real-time applications in Laravel:

  • Pusher - third-party service (paid) that allows us to build real-time applications.
  • Laravel WebSockets - a package from BeyondCode (Now Archived)
  • Soketi - alternative to Pusher, but free (self-hosted)

Reverb was created to simplify the process of configuration and owning that problem as a first-party package.

Now, let's see how we can use Reverb in our Laravel application.


Project Setup

We will use Laravel 11 for this tutorial with Breeze as our authentication system. From there, we have a simple "Dashboard" page:

From here, we will install Reverb and create a few simple real-time events to show how it works.


Installing Reverb

To install Reverb, we have to call this command:

php artisan install:broadcasting

This will ask us if we want to install Reverb, enter yes and press Enter.

Once the package installs, it will ask...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

CP
Claudio Pereira ✓ Link copied!

Povilas, once again, congratulations on the content!

CP
Claudio Pereira ✓ Link copied!

Could you and your team create specific examples for Filament using database notifications?Could you and your team create specific examples for Filament using database notifications? Thank you in advance for this! 😊

M
Modestas ✓ Link copied!

Can you expand on your request a little bit? I don't think that there is something complicated in database notifications there :)

GK
Gavin Kimpson ✓ Link copied!

Exactly what the people wanted! Cannot wait to delve into this thanks again!

GK
Gavin Kimpson ✓ Link copied!

After starting the reverb server I appear to get an error - anyone else having the same issue, I have cloned the github repo?

php artisan reverb:start

   INFO  Starting server on 0.0.0.0:8080.


   TypeError

  Laravel\Reverb\ConfigApplicationProvider::findById(): Argument #1 ($id) must be of type string, null given, called in /Users/gavin/Herd/laravel-reverb-notifications/vendor/laravel/reverb/src/ConfigApplicationProvider.php on line 27

  at vendor/laravel/reverb/src/ConfigApplicationProvider.php:36
     32▕      * Find an application instance by ID.
     33▕      *
     34▕      * @throws \Laravel\Reverb\Exceptions\InvalidApplication
     35▕      */
  ➜  36▕     public function findById(string $id): Application
     37▕     {
     38▕         return $this->find('app_id', $id);
     39▕     }
     40▕

      +1 vendor frames

  2   [internal]:0
      Laravel\Reverb\ConfigApplicationProvider::Laravel\Reverb\{closure}()
      +34 vendor frames

  37  artisan:13
      Illuminate\Foundation\Application::handleCommand(Object(Symfony\Component\Console\Input\ArgvInput))
M
Modestas ✓ Link copied!

.env file is missing configurations... for whatever reason installation only added to real .env file and not into example!

I will update them in the morning (or you can find them by running the install command again)

GK
Gavin Kimpson ✓ Link copied!

I'll have to try again tomorrow - appear to have sorted the .env now by added the reverb env entries however now I seem to have this constantly in my Chrome browser console, I presume my local setup may require tweaking... I am using Herd currently (e.g all my dev urls end in .test)

GET http://127.0.0.1:5173/ net::ERR_CONNECTION_REFUSED
M
Modestas ✓ Link copied!

This seems okay! It probably does not match the port in the .env file ( tho I did not test it on herd )

GK
Gavin Kimpson ✓ Link copied!

Weirdly it seems to be all connected now in the WS tab in Chrome but running the artisan commands did nothing... i'll wait for the updated repo and hopefully someone one using Herd can point me in the right direction

M
Modestas ✓ Link copied!

Hey, updated the repository to have .env.example filled with values that worked on my end! Hopefully this works (and you can compare it with what you put on!)

C
Cesar ✓ Link copied!

Hi, is it necessary to run php artisan queue:listen? Because without it, it doesn't work.

M
Modestas ✓ Link copied!

Hi, no, if you don't use queues. Change your .env driver from redis to sync and it should start working again

C
Cesar ✓ Link copied!

Thank you very much for your response.

M
marcelo-kazalukian ✓ Link copied!

Hi. It's better if you put this in the content course because Laravel 11 comes with QUEUE_CONNECTION=database by default. It took me a while fixed it.

Cheers.

GK
Gavin Kimpson ✓ Link copied!

did you guys manage to get this working for you?

IL
Inamras Luzd ✓ Link copied!

I followed exactly and even used the repo (generated a new key, changed from sqlite to mysql with the proper credentials and created a couple of users). I don't get the response as advertised. There are no errors in the console. console.log(event); shows nothing.

M
Modestas ✓ Link copied!

Have you launched reverb and a queue worker?

IL
Inamras Luzd ✓ Link copied!

Not sure if I'm doing it right, but here's what I did:

  • php artisan serve
  • php artisan reverb:start
  • php artisan queue:work
  • php artisan system:notify-maintenance (and proceeded to enter a future date)
M
Modestas ✓ Link copied!

could you run:

php artisan reverb:start --debug

and see what it outputs?

also, please check browser networks "ws" tab to see if it connected to sockets

IL
Inamras Luzd ✓ Link copied!

Running php artisan reverb:start --debug outputs this:

{
    "event": "SystemMaintenanceEvent",
    "data": {
        "time": "2024-07-03"
    },
    "channel": "system-maintenance"
}

The ws Messages:

channel: "system-maintenance"
data: "{\"time\":\"2024-07-03\"}"
event: "SystemMaintenanceEvent"```

Request URL:
ws://127.0.0.1:8080/app/vsthk74otyhwvr62kvka?protocol=7&client=js&version=8.4.0-rc2&flash=false
Request Method:
GET
Status Code:
101 Switching Protocols
M
Modestas ✓ Link copied!

It seems that the event is triggered and ws message is retrieved... but now I wonder why it did not update on the UI for you. There was no console logs for any error? Or maybe you have an adblocker running?

IL
Inamras Luzd ✓ Link copied!

console.log(event) yielded nothing. No adblockers and even turned off firewall.

M
Modestas ✓ Link copied!

Hmm, this is weird. Last question then:

Is your .env configured correctly with the REVERB variables? If they are and you still need help - feel free to email us (mark in the email that it should be forwarded to Modestas) and I'll assist you there as much as I can :) (ps. Same can be done in our discord!)

B
Babis ✓ Link copied!

try to use the simple notification and i see in console Cannot read properties of undefined (reading 'channel')

M
Modestas ✓ Link copied!

dis you compile your assets?

B
Babis ✓ Link copied!

Yes, new laravel installation,

  1. npm run build
  2. php artisan serve
M
Modestas ✓ Link copied!

I would check that echo.js is loaded in the website assets and is correctly included

B
Babis ✓ Link copied!

echo.js

import Echo from 'laravel-echo';

import Pusher from 'pusher-js'; window.Pusher = Pusher;

window.Echo = new Echo({ broadcaster: 'reverb', key: import.meta.env.VITE_REVERB_APP_KEY, wsHost: import.meta.env.VITE_REVERB_HOST, wsPort: import.meta.env.VITE_REVERB_PORT ?? 80, wssPort: import.meta.env.VITE_REVERB_PORT ?? 443, forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https', enabledTransports: ['ws', 'wss'], });

M
Modestas ✓ Link copied!

That wasn't what I was referring to, but also check if everything is wrapped in:

window.addEventListener('DOMContentLoaded', function () { ... })

Because this is important.

B
Babis ✓ Link copied!

In fresh installation i put the following in welcome.blade.php before the body close

<script> window.addEventListener('DOMContentLoaded', function () { window.Echo.channel('system-maintenance') .listen('SystemMaintenanceEvent', (event) => { console.log(event) }); }); </script>
M
Modestas ✓ Link copied!

Okay, did you install the broadcasting package?

B
Babis ✓ Link copied!

Yes i followed all steps and also run php artisan reverb:start

B
Babis ✓ Link copied!

finally the error was i didnt have the following on head @vite(['resources/css/app.css', 'resources/js/app.js'])

But i see another error in console now wss://localhost:8080/app/3jxinlvwqfw6zd6q929e?protocol=7&client=js&version=8.4.0-rc2&flash=false failed: WebSocket is closed before the connection is established.

GK
Gavin Kimpson ✓ Link copied!

i get all the same problems

M
mymasjidlink ✓ Link copied!

hy giuys have you solved the issue of reverb?

HM
Hossam Mohamed ✓ Link copied!

the event is triggered and ws message is retrieved... but I wonder why it did not update on the UI for me. There was no errors at console logs, what is the problem?

when write command :

Message Handled .............................................................................................................. 339232170.221969025 Pruning Stale Connections ........................................................................................................................ Pinging Inactive Connections ..................................................................................................................... Message Received ............................................................................................................. 339232170.221969025

1▕ {

2▕ "event": "pusher:ping",

3▕ "data": []

4▕ }

console error: Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received

how can I get

Reverb configuration

REVERB_APP_ID= REVERB_APP_KEY= REVERB_APP_SECRET= REVERB_HOST="localhost" REVERB_PORT=8080 REVERB_SCHEME=http

should I let the reverb config as you show at github Repo or use my one and how to create it ?

M
Modestas ✓ Link copied!

Sorry, the formatting of the message is a bit messed up...

  1. Ping is not the event you should see in the log. You should see your own named event there in order for it to work
  2. There is some kind of an error, hard to say what.
  3. To get the configuration - you have to fill it yourself or run the php artisan broadcasting:install command.

As for why the UI would not update - as soon as you see the correctly named event apear in your WS console - you should see UI update. If that's not the case, check for js errors in browser console

HM
Hossam Mohamed ✓ Link copied!

I clonning the repo from github with regenerate key and install Composer at first and cp .env ...and all of this why the reverb not working and before use reverb also pusher was not working !!

M
Modestas ✓ Link copied!

Yes, but our .env.example does not have all values filled for the REVERB configuration, so they should be configured as needed :)

But if you also had issues with pusher before - then there might be something else wrong. Like a port being blocked or something else like that

HM
Hossam Mohamed ✓ Link copied!

I am sorry for many comments but I want to show you the new error i get at console , WebSocket connection to 'ws://localhost:8080/app/3prtjfbbgn54t6w8diu0?protocol=7&client=js&version=8.4.0-rc2&flash=false' failed:

If you have any ideas or solutions , thanks for laravel daily team

GK
Gavin Kimpson ✓ Link copied!

if anyone manages to get around the problems please let me know ❤️

M
Modestas ✓ Link copied!

This error message can mean A LOT of different things sadly, so it's hard to say what is happening there.

But from what I've learned:

If you are using docker/WSL2/windows setup - the whole reverb thing can become really tricky to get working. And sadly, I we don't have the solution for these problems... What I can suggest is - taking the whole setup from scratch and doing it like it's written in the documentation. Then adding the parts that are missing from our tutorial :) That sometimes helps people

MS
Mo Said ✓ Link copied!

Hi, Thanks for the example I have implemented using filament below code sends and displays broadcasted notification properly on the frontend but it is not saved on default notification database for later viewing like when using notification database method. how to save notifications to database when using broadcast method?

	   $title = $data['title'];
            $message = $data['message'];
            $user = auth()->user();
            $url = $data['url'];

            $user->notify(
                Notification::make()
                ->success()
                ->title($title)
                ->body($message)
                ->persistent()
                ->actions([
                Action::make('View')
                    ->button()
                    ->url($url),
                ])
                ->toBroadcast(),
            );
MS
Mo Said ✓ Link copied!

After some trial and erros I managed to do it, I hope it will be helpful to someone else

            $title = $data['title'];
            $message = $data['message'];
            $url = $data['url'];
            $user = User::find($data['user_id']);

            Notification::make()
            ->success()
            ->title($title)
            ->body($message)
            //->persistent()
            ->actions([
                Action::make('View')
                    ->button()
                    ->url($url, shouldOpenInNewTab: true),
            ])
            ->broadcast($user)
           //queue:listen or queue:work should be running so that the notification will be displayed under the notifications modal panel (Bell Icon)
            ->sendToDatabase($user) 
            ->send();
            // use instead of database polling
            event(new DatabaseNotificationsSent($user)); 
V
Vadim ✓ Link copied!

There is no need to add/pass the DIV with all the styling throug javascript.

You can have it all already on the page, just hidden. Then use Reverb/Websockets to just switch visibility, or pass some message and switch visibility.

Anyway, it's way more convenient to have your HTML/CSS on the HTML part of the page, rather than in JS.

AS
Abdulbasit Salah ✓ Link copied!

i am facing this issue while running the command Pusher error: cURL error 28: Operation timed out after 30006 milliseconds with 0 bytes received (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://localhost:8080/apps/192749/events?auth_key=cgny6goqtw200yh15tvb&auth_timestamp=1727337534&auth_version=1.0&body_md5=07eed6f0f66bd806d259a3bc4b275b9b&auth_signature=260f16da1b4a2c2156ae8f8f979ea0e68d326dfd8bd87705264a40c2bc881f74.

SS
Steven Stratford ✓ Link copied!

Hello, I was trying the public notification. I was logged in as "Admin" and got the message with the date, everything ok. If i switch the user to "User1" for example and fire an new event over the console command i am not getting the message. I have to restart reverb and fire an event again to get the message.
What do i miss ?

M
Modestas ✓ Link copied!

Hmm, it should not be impacted by the connection.

When creating this article, I've tested the logging in/out workflows quite a few times and did not see an issue with this...

Have you tried running reverb in debug mode? Does it show the event?

SS
Steven Stratford ✓ Link copied!

Yes, i had de debug mode on and its not showing the message if i logged out and in as differnt user. But if use two diffren Browser (or private mode) and log in with two diffrent user it works. I see on the message on both browsern at the same time. I have to check what happen if i logout with one and login with a diffrent user on ohne of the browsern and leave the other logged in.

NI
Nur ikhsan ✓ Link copied!

hello, i get same problem. when i try php artisan reverb:start --debug always showing {

2▕ "event": "pusher:subscribe",

3▕ "data": {

4▕ "auth": "",

5▕ "channel": "system-maintenance"

6▕ }

7▕ } I've tried looking for a solution like on stackoverflow and others but I still can't find it. Can you help explain to me what the cause is

M
Modestas ✓ Link copied!

I'm not sure what the issue is here. This seems normal, since as soon as you subscribe to a channel - this message should pop up.

NI
Nur ikhsan ✓ Link copied!

and I run it with the command

  1. php artisan reverb:start
    1. php artisan queue:listen
    1. php artisan system:notify-maintenance the message still can't be sent but when I match the port I use in the application and reverb, the message is can be sent. My application is on port 81 and reverb is on port 8080, I equalize the reverb port on 81, messages can be sent but my application can't be opened. is there another setting I'm missing?
M
Modestas ✓ Link copied!

app and reverb should be running on separate ports.

You could check network tab for any issues with wss connection

NI
Nur ikhsan ✓ Link copied!

it is now up and running, i am using nginx and nginx.conf i added /ws to location location /ws { proxy_pass http://localhost:6001; # Change to your WebSocket server address proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }

M
mymasjidlink ✓ Link copied!

php artisan system:maintenance scheduled "14:30" "Server updates will be applied." Maintenance notification sent with status: scheduled

but no notification is there in the console nor the message is printing

Err: Uncaught (in promise) Error: redacted

please help me solve this sir

M
mymasjidlink ✓ Link copied!

please answer to my query?

MD
Michael Dance ✓ Link copied!

Hi there, I had problems with the Who's online so I thought I'd come and try this on instead from scratch to see if it's a me problem or I'm doing something wrong. I can't get reverb working for some reason.

In my .env:

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
BROADCAST_CONNECTION=reverb
CACHE_STORE=database
QUEUE_CONNECTION=database
SESSION_DRIVER=database
SESSION_LIFETIME=120

REVERB_APP_ID=1
REVERB_APP_KEY=456789uyfd23ghj78
REVERB_APP_SECRET=098ikjhgfdew342wer67uyhg
REVERB_PORT=8080
REVERB_SCHEME=http

I've followed your guide to the T and I can't get the debug to output.

php artisan reverb:start --debug

   INFO  Starting server on 0.0.0.0:8080.  

  Pruning Stale Connections ............................................................................................................  
  Pinging Inactive Connections .........................................................................................................  
  Pruning Stale Connections ............................................................................................................  
  Pinging Inactive Connections .........................................................................................................  

When I run the command:

php artisan system:notify-maintenance

 When should it happen?:
 > 20:00

Thank you for your help and hopefully I can get Reverb working the bugger haha.

I'm using this on a vps and not localhost does that effect the use of broadcasting?

M
Modestas ✓ Link copied!

Your broadcast driver is:

BROADCAST_DRIVER=log

Try to change that to reverb

MD
Michael Dance ✓ Link copied!

Thank you for getting back to me fast, I've changed that.

Ran npm run build, then restarted reverb: php artisan reverb:start --debug and re-ran the code again:

php artisan system:notify-maintenance

 When should it happen?:
 > 20:00

And nothing but in the safari browser inspect element it's moaning about these: You must pass your app key when you instantiate Pusher. on app.js

And this bit on your code for the layouts to show the event:

TypeError: undefined is not an object (evaluating 'window.Echo.channel')

Which is on:

window.Echo.channel('system-maintenance')

Thank you for your help.

M
Modestas ✓ Link copied!

It seems that it's trying to launch pusher at this point. Which is not really what you are trying to do here.

Check that:

  • You have correct .env information filled
  • That you deploy that information (for example, you haven't cached wrong .env values)

But honestly, it's really hard to try and debug this via comments. Often it's some small value misconfigured :)

MD
Michael Dance ✓ Link copied!

Thanks mate,

I tried to remove Pusher but got this: laravel/reverb v1.4.8 requires pusher/pusher-php-server (^7.2)

So just removed the .env details relating to pusher, and edited the broadcasting to remove it by following the docs: https://laravel.com/docs/12.x/broadcasting#pusher-channels

Didn't fix anything but thank you for your help I need to dive into this more as it's a pain in the bum haha.

M
Modestas ✓ Link copied!

Oh no, I did not mean to remove it - more to check that no settings use it!

For faster debugging - launch a new project with reverb (fresh laravel), check the configs and see the differences :)

MD
Michael Dance ✓ Link copied!

Thank you, I created a new app, followed the basics of the tutorial on Laravel 12, to the bit where it should echo a date in like a var_dump.

And I don't get that, I get an error message about the channel.

Thanks for your help mate.

M
Modestas ✓ Link copied!

This seems that Echo wasn't correctly registered/loaded in the app.js file. Or it wasn't included in your template - check that :)

MD
Michael Dance ✓ Link copied!

thank you for your fast reply mate, this is what i have in my resources/js/app.js

M
Modestas ✓ Link copied!

Did you compile the assets with 'npm run build'? And did you include the compiled js files into your app?

ps. Compiling assets - saves the keys in js files. So any changes to config and you have to re-compile

MD
Michael Dance ✓ Link copied!

npm run build mate?

M
Modestas ✓ Link copied!

Yes! You have to compile the assets with nom so that they would be used :)

Unless you had something else in mind?

MD
Michael Dance ✓ Link copied!

yeah i run that alot to rebuild any changes. but it didn't fix it, weirdly i'm using the livewire starter kit.

M
Modestas ✓ Link copied!

It doesnt matter which kit, since they all use same logic :)

But that is still weird...

MD
Michael Dance ✓ Link copied!

so confused haha

RA
Richard A. Hoyle ✓ Link copied!

Grate course and even more help area however I can not get the Message "WARNING: The system will go down for maintenance at 2025-05-21" on the Dashboard page Every thing seems to be working but this.

One note I had to make shour that the REDIS_PORT= "8080 " and the REVERB_PORT= "8080 " Were the same or you will get an error like I did.

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.