Send notifications across multiple channels—email, SMS, Slack, and database—from a single notification class using Laravel’s unified notification system.
Notifications are short, informational messages sent to users when something happens in your application—an invoice is paid, a password is reset, a deployment completes.Unlike mailables, a single notification class can deliver its message across multiple channels. The same InvoicePaid notification can send an email and save a database record simultaneously.
Define a toMail method on the notification to format the email:
use Illuminate\Notifications\Messages\MailMessage;/** * Get the mail representation of the notification. */public function toMail(object $notifiable): MailMessage{ return (new MailMessage) ->subject('Invoice Paid') ->greeting('Hello '.$notifiable->name.'!') ->line('Your invoice #'.$this->invoice->id.' has been paid.') ->action('View Invoice', route('invoices.show', $this->invoice)) ->line('Thank you for your business.');}
Define a toSlack method after connecting a Slack app to your workspace:
use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;use Illuminate\Notifications\Slack\SlackMessage;public function toSlack(object $notifiable): SlackMessage{ return (new SlackMessage) ->text('Invoice #'.$this->invoice->id.' has been paid.') ->headerBlock('Payment Received') ->sectionBlock(function (SectionBlock $block) { $block->text('Amount: $'.$this->invoice->amount); });}
<?phpnamespace App\Notifications;use App\Models\Invoice;use Illuminate\Bus\Queueable;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Notifications\Messages\MailMessage;use Illuminate\Notifications\Notification;class InvoicePaid extends Notification implements ShouldQueue{ use Queueable; public function __construct( public Invoice $invoice, ) {} /** * Get the notification's delivery channels. * * @return array<int, string> */ public function via(object $notifiable): array { return ['mail', 'database']; } /** * Get the mail representation of the notification. */ public function toMail(object $notifiable): MailMessage { return (new MailMessage) ->subject('Invoice Paid') ->line('Invoice #'.$this->invoice->id.' has been paid.') ->action('View Invoice', route('invoices.show', $this->invoice)) ->line('Thank you for using our service.'); } /** * Get the array representation of the notification. * * @return array<string, mixed> */ public function toArray(object $notifiable): array { return [ 'invoice_id' => $this->invoice->id, 'amount' => $this->invoice->amount, ]; }}
3
Send the notification
use App\Notifications\InvoicePaid;public function pay(Invoice $invoice): RedirectResponse{ $invoice->markAsPaid(); $invoice->user->notify(new InvoicePaid($invoice)); return redirect()->route('invoices.show', $invoice) ->with('success', 'Invoice paid successfully.');}
4
Display in-app notifications
@foreach(auth()->user()->unreadNotifications as $notification) <div class="notification"> Invoice #{{ $notification->data['invoice_id'] }} was paid. <form method="POST" action="/notifications/{{ $notification->id }}/read"> @csrf <button type="submit">Mark as Read</button> </form> </div>@endforeach
Use Notification::fake() to assert notifications are sent without actually delivering them:
Pest
PHPUnit
use App\Notifications\InvoicePaid;use Illuminate\Support\Facades\Notification;test('user is notified when invoice is paid', function () { Notification::fake(); $user = User::factory()->create(); $invoice = Invoice::factory()->for($user)->create(); $this->post("/invoices/{$invoice->id}/pay"); Notification::assertSentTo($user, InvoicePaid::class, function ($notification) use ($invoice) { return $notification->invoice->id === $invoice->id; });});
use App\Notifications\InvoicePaid;use Illuminate\Support\Facades\Notification;public function test_user_is_notified_when_invoice_is_paid(): void{ Notification::fake(); $user = User::factory()->create(); $invoice = Invoice::factory()->for($user)->create(); $this->post("/invoices/{$invoice->id}/pay"); Notification::assertSentTo($user, InvoicePaid::class, function ($notification) use ($invoice) { return $notification->invoice->id === $invoice->id; });}
Mail
Learn how to build rich HTML email templates with mailable classes and Markdown components.