Laravel Notifications — Database, Mail, SMS, and Slack Alerts
In this tutorial, you will learn about Laravel Notifications. We cover key concepts, practical examples, and best practices to help you master this topic.
Laravel notifications send alerts through mail, SMS, Slack, database, broadcast, and custom channels using a single notification class with channel-specific formatting.
What You'll Learn
By the end of this tutorial, you'll create notification classes, send through multiple channels, use database notifications for in-app alerts, send SMS with Vonage, and customize notification delivery.
Why Notifications Matter
Applications must reach users through their preferred channels. Laravel notifications route different channels from one class, keeping notification logic centralized.
Real-World Use
An order system sends a database notification for in-app alerts, an email receipt, and an SMS for shipping updates, all from one OrderShipped notification class.
Notifications Path
flowchart LR
A[Laravel Framework] --> B[Notifications]
B --> C[Mail Channel]
B --> D[Database]
B --> E[SMS Vonage]
B --> F[Slack]
B --> G{You Are Here}
style G fill:#f90,color:#fff
Creating Notifications
Generate a notification with multiple channels.
php artisan make:notification OrderShipped
<?php
namespace App\Notifications;
use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\NexmoMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
class OrderShipped extends Notification implements ShouldQueue {
use Queueable;
public function __construct(
public Order $order,
) {}
public function via(object $notifiable): array {
$channels = ["database"];
if ($notifiable->notification_preferences["email"] ?? true) {
$channels[] = "mail";
}
if ($notifiable->phone && ($notifiable->notification_preferences["sms"] ?? false)) {
$channels[] = "nexmo";
}
return $channels;
}
}
Mail Channel
Format the email notification.
<?php
public function toMail(object $notifiable): MailMessage {
return (new MailMessage)
->subject("Order #{$this->order->id} Shipped")
->greeting("Hello {$notifiable->name}!")
->line("Your order #{$this->order->id} has been shipped!")
->line("Total: $" . number_format($this->order->total, 2))
->action("Track Order", url("/orders/{$this->order->id}"))
->line("Thank you for your business!")
->cc("shipping@example.com")
->bcc("archive@example.com");
}
Database Channel
Store notifications in the notifications table.
<?php
public function toDatabase(object $notifiable): array {
return [
"order_id" => $this->order->id,
"order_total" => $this->order->total,
"status" => $this->order->status,
"message" => "Order #{$this->order->id} has been shipped",
];
}
// Mark as read
$user->unreadNotifications->markAsRead();
$user->notifications()->where("id", $id)->update(["read_at" => now()]);
Slack Channel
Send notifications to Slack channels.
<?php
public function toSlack(object $notifiable): SlackMessage {
return (new SlackMessage)
->from("Order Bot", ":package:")
->to("#shipping")
->content("Order #{$this->order->id} shipped!")
->attachment(function ($attachment) {
$attachment->title("Order Details", url("/orders/{$this->order->id}"))
->fields([
"Customer" => $this->order->user->name,
"Total" => "$" . number_format($this->order->total, 2),
"Items" => $this->order->items->count(),
]);
});
}
Sending Notifications
Send notifications to notifiable entities.
<?php
// To a single user
$user->notify(new OrderShipped($order));
// To multiple users
Notification::send($admins, new NewUserRegistered($user));
// On-demand notification
use Illuminate\Support\Facades\Notification;
Notification::route("mail", "guest@example.com")
->route("slack", "#general")
->notify(new WelcomeNotification());
Common Mistakes
1. Not Queuing Notifications
Notifications sent synchronously slow down requests. Always implement ShouldQueue.
2. Ignoring Notification Preferences
Sending through all channels annoys users. Check user preferences in via().
3. Not Using Database Notifications for In-App
Database notifications are the only channel that persists for in-app display.
4. Sending SMS for Non-Critical Alerts
SMS costs add up. Reserve SMS for critical alerts like password resets or payment failures.
5. Forgetting to Add Notifiable Trait
Models must use Notifiable trait to send notifications.
Practice Questions
1. What is the via() method for?
Returning an array of channels the notification should be sent through.
2. How do you queue notifications?
Implement the ShouldQueue interface on the notification class.
3. What is an on-demand notification?
A notification sent to a route without a notifiable model.
4. How do you mark a database notification as read?
Call markAsRead() on the notification model instance.
5. Challenge: Create a multi-channel notification with preferences.
<?php
class InvoiceAvailable extends Notification implements ShouldQueue {
public function via($notifiable): array {
$channels = [];
if ($notifiable->prefers_mail) $channels[] = "mail";
if ($notifiable->prefers_database) $channels[] = "database";
if ($notifiable->prefers_sms && !app()->isLocal()) $channels[] = "nexmo";
return $channels;
}
}
FAQ
Mini Project: Multi-Channel Notification System
Build a notification system with preferences and queuing.
<?php
class PaymentReceived extends Notification implements ShouldQueue {
public function via($notifiable): array {
return [
"database",
...($notifiable->email_verified_at ? ["mail"] : []),
...($notifiable->phone ? ["nexmo"] : []),
];
}
}
What's Next
Laravel Mail Laravel Queues Deep Laravel Broadcasting
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro