Skip to main content

Documentation Index

Fetch the complete documentation index at: https://kawax.biz/llms.txt

Use this file to discover all available pages before exploring further.

What are notifications?

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.

Generating notifications

Create a notification with Artisan:
php artisan make:notification InvoicePaid
This generates app/Notifications/InvoicePaid.php.

Sending notifications

Via the notifiable trait

The App\Models\User model includes the Notifiable trait by default, which exposes a notify method:
use App\Notifications\InvoicePaid;

$user->notify(new InvoicePaid($invoice));
You can add Notifiable to any model, not just User.

Via the Notification facade

Send to multiple users at once using the Notification facade:
use Illuminate\Support\Facades\Notification;

Notification::send($users, new InvoicePaid($invoice));

Specifying delivery channels

Every notification class has a via method that returns which channels to use:
/**
 * Get the notification's delivery channels.
 *
 * @return array<int, string>
 */
public function via(object $notifiable): array
{
    return ['mail', 'database'];
}
Built-in channels:
ChannelDescription
mailSend via email
databaseStore in the database for in-app display
broadcastBroadcast over WebSockets
vonageSend SMS via Vonage
slackSend to a Slack channel
You can also route to a specific channel based on user preferences:
public function via(object $notifiable): array
{
    return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
}

Mail notifications

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.');
}

Markdown mail notifications

Generate a notification with a Markdown template for full HTML control:
php artisan make:notification InvoicePaid --markdown=notifications.invoice-paid
Use markdown instead of chaining MailMessage methods:
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
        ->markdown('notifications.invoice-paid', [
            'invoice' => $this->invoice,
            'user' => $notifiable,
        ]);
}

Database notifications

Store notifications in a database table and display them in your UI.

Setup

Create the notifications table:
php artisan make:notifications-table
php artisan migrate
Add database to the via method, then define a toDatabase (or toArray) method returning an array of data:
/**
 * Get the array representation of the notification.
 *
 * @return array<string, mixed>
 */
public function toDatabase(object $notifiable): array
{
    return [
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ];
}

Reading notifications

Access a user’s notifications through the notifications relationship:
$user = Auth::user();

foreach ($user->unreadNotifications as $notification) {
    echo $notification->data['invoice_id'];
}
Mark notifications as read:
// Mark one as read
$notification->markAsRead();

// Mark all as read
$user->unreadNotifications->markAsRead();

Queueing notifications

Notifications that call external services should be queued. Add ShouldQueue and Queueable:
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;

    // ...
}
Now $user->notify(new InvoicePaid($invoice)) queues the notification automatically.

Delaying delivery

$user->notify(
    (new InvoicePaid($invoice))->delay(now()->addMinutes(10))
);
Delay different channels by different amounts:
$user->notify(
    (new InvoicePaid($invoice))->delay([
        'mail' => now()->addMinutes(5),
        'sms'  => now()->addMinutes(10),
    ])
);

On-demand notifications

Send a notification to a recipient who isn’t stored in your database:
use Illuminate\Support\Facades\Notification;

Notification::route('mail', '[email protected]')
    ->route('vonage', '5555555555')
    ->notify(new InvoicePaid($invoice));

Slack notifications

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);
        });
}

A complete example

1

Generate the notification

php artisan make:notification InvoicePaid
2

Write the notification class

<?php

namespace 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

Testing notifications

Use Notification::fake() to assert notifications are sent without actually delivering them:
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;
    });
});

Mail

Learn how to build rich HTML email templates with mailable classes and Markdown components.
Last modified on April 19, 2026