> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Notifications

> Send notifications across multiple channels—email, SMS, Slack, and database—from a single notification class using Laravel's unified notification system.

## 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:

```shell theme={null}
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:

```php theme={null}
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:

```php theme={null}
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:

```mermaid theme={null}
flowchart TD
    A["$user->notify(new InvoicePaid())"] --> B["via() determines<br>channels"]
    B --> C{"Channel selection"}
    C --> D["mail<br>toMail()"]
    C --> E["database<br>toArray()"]
    C --> F["broadcast<br>toBroadcast()"]
    C --> G["vonage<br>toVonage()"]
    C --> H["slack<br>toSlack()"]
```

```php theme={null}
/**
 * Get the notification's delivery channels.
 *
 * @return array<int, string>
 */
public function via(object $notifiable): array
{
    return ['mail', 'database'];
}
```

Built-in channels:

| Channel     | Description                              |
| ----------- | ---------------------------------------- |
| `mail`      | Send via email                           |
| `database`  | Store in the database for in-app display |
| `broadcast` | Broadcast over WebSockets                |
| `vonage`    | Send SMS via Vonage                      |
| `slack`     | Send to a Slack channel                  |

You can also route to a specific channel based on user preferences:

```php theme={null}
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:

```php theme={null}
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:

```shell theme={null}
php artisan make:notification InvoicePaid --markdown=notifications.invoice-paid
```

Use `markdown` instead of chaining `MailMessage` methods:

```php theme={null}
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:

```shell theme={null}
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:

```php theme={null}
/**
 * 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:

```php theme={null}
$user = Auth::user();

foreach ($user->unreadNotifications as $notification) {
    echo $notification->data['invoice_id'];
}
```

Mark notifications as read:

```php theme={null}
// 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 theme={null}
<?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

```php theme={null}
$user->notify(
    (new InvoicePaid($invoice))->delay(now()->addMinutes(10))
);
```

Delay different channels by different amounts:

```php theme={null}
$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:

```php theme={null}
use Illuminate\Support\Facades\Notification;

Notification::route('mail', 'hello@example.com')
    ->route('vonage', '5555555555')
    ->notify(new InvoicePaid($invoice));
```

## Slack notifications

Define a `toSlack` method after connecting a Slack app to your workspace:

```php theme={null}
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

<Steps>
  <Step title="Generate the notification">
    ```shell theme={null}
    php artisan make:notification InvoicePaid
    ```
  </Step>

  <Step title="Write the notification class">
    ```php theme={null}
    <?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,
            ];
        }
    }
    ```
  </Step>

  <Step title="Send the notification">
    ```php theme={null}
    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.');
    }
    ```
  </Step>

  <Step title="Display in-app notifications">
    ```blade theme={null}
    @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
    ```
  </Step>
</Steps>

## Testing notifications

Use `Notification::fake()` to assert notifications are sent without actually delivering them:

<Tabs>
  <Tab title="Pest">
    ```php theme={null}
    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;
        });
    });
    ```
  </Tab>

  <Tab title="PHPUnit">
    ```php theme={null}
    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;
        });
    }
    ```
  </Tab>
</Tabs>

<Card title="Mail" icon="envelope" href="/en/mail">
  Learn how to build rich HTML email templates with mailable classes and Markdown components.
</Card>


## Related topics

- [BlueskyManager and HasShortHand](/en/packages/laravel-bluesky/bluesky-manager.md)
- [Notification channel - Laravel Bluesky](/en/packages/laravel-bluesky/notification.md)
- [Laravel Notification for Discord(Webhook)](/en/packages/laravel-notification-discord-webhook.md)
- [Notifications - LINE SDK for Laravel](/en/packages/laravel-line-sdk/notification.md)
- [Tutorial - Laravel Console Starter](/en/packages/laravel-console-starter/tutorial.md)
