Laravel Notifications help you send alerts via email, SMS, and database. Learn how to implement multi-channel messaging in your app with this practical guide.
Last month, I spent about three days refactoring a legacy notification service that was hardcoded to send only emails. When the product team asked for SMS and in-app alerts, the existing code essentially turned into a giant, unreadable switch statement. That’s when I moved the entire flow over to Laravel Notifications, and honestly, it’s one of the cleanest abstractions in the framework.
Instead of binding your business logic to a specific delivery method, Laravel lets you define a notification class that acts as a blueprint. You decide where it goes, and the framework handles the heavy lifting.
At its core, a notification is a class that specifies the "channels" it should be delivered through. You don't need to worry about the underlying implementation of the mailer or the SMS provider inside your controller. You just trigger the notification, and Laravel routes it to the right place.
If you’re already familiar with the basics of sending transactional emails, you might have read my previous post on Laravel Mail: A Beginner's Guide to Sending Transactional Emails, which covers the transport configuration you’ll need here.
To start, generate a notification class using Artisan:
Bashphp artisan make:notification OrderShipped
This creates a file in app/Notifications. Inside, you’ll find two main methods: via() and toMail(). The via() method is where the magic happens. You return an array of channels:
PHPpublic function via($notifiable) { return ['mail', 'database']; }
If you want to add Laravel SMS support later, you simply add vonage or twilio to that array. It’s that simple.
One of the most common requirements is storing alerts so users can see them in their dashboard. Database Notifications provide a built-in table schema to handle this without writing custom migrations.
First, run the artisan command to create the notification table:
Bashphp artisan notifications:table php artisan migrate
Now, update your OrderShipped class to include a toArray() method. This defines how the notification data is stored in the JSON column of your database:
PHPpublic function toArray($notifiable) { return [ 'order_id' => $this->order->id, 'message' => 'Your order has been shipped!', ]; }
You can send notifications via the Notifiable trait, which is included in the default User model. Just call the notify method:
PHP$user->notify(new OrderShipped($order));
We initially tried to send these synchronously, but that caused a lag of around 400ms on the checkout page because the mail driver had to connect to the SMTP server. To fix this, we implemented background processing, as discussed in Mastering Laravel Queues: A Beginner’s Guide to Background Processing. By implementing the ShouldQueue interface on the notification class, Laravel automatically pushes the delivery to your queue workers.
One thing to watch out for is the "notifiable" object. By default, Laravel expects the email property on the model. If you’re using Laravel SMS or other custom channels, you might need to define a routeNotificationForVonage() method on your User model to tell the system which phone number to use.
If you don't define these routing methods, the notification will fail silently or throw an exception, depending on your environment settings. Always test your channels in local using a tool like Mailpit or a mock SMS service.
php artisan queue:work, your notifications will never actually be sent.via() method. If the logic gets too complex, consider using a separate notification class for different scenarios.notifications table can grow quickly. Remember to prune old notifications using the model:prune command or a scheduled task.Can I send the same notification to multiple channels?
Yes, just return an array like ['mail', 'database', 'slack'] in the via() method.
How do I customize the database table name?
Laravel defaults to a table named notifications. While you can change this, I recommend sticking to the default to avoid unnecessary configuration headaches.
Is there a way to notify users who aren't in the database?
Yes, you can use the Notification::route() facade to send alerts to an arbitrary email address or phone number without needing an Eloquent model.
I’m still experimenting with how to handle notification preferences (e.g., letting users toggle email vs. SMS). Right now, I keep an settings column in the users table and check that inside the via() method, but it feels a bit repetitive. If you find a cleaner way to handle user-specific notification preferences, I’d love to hear how you’re doing it.
Mastering Laravel config files and environment variables is essential for clean code. Learn how to manage your settings effectively in this practical guide.