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

# E-mail versturen

> Van de basis van e-mail versturen met de Mailable-klassen van Laravel tot Markdown-mails en versturen via de queue.

## Wat is de mailfunctionaliteit van Laravel

De mailfunctionaliteit van Laravel is gebouwd op [Symfony Mailer](https://symfony.com/doc/current/mailer.html) en ondersteunt drivers als SMTP, Mailgun, Postmark, Resend, Amazon SES en sendmail.

<Info>
  SwiftMailer, dat in oudere versies van Laravel werd gebruikt, is uitgefaseerd. Vanaf Laravel 9 wordt Symfony Mailer gebruikt.
</Info>

De mailconfiguratie beheer je in `config/mail.php`. In het `.env`-bestand wissel je van driver.

```ini theme={null}
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=your-username
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
```

## Een Mailable-klasse aanmaken

In Laravel wordt elke e-mail die de applicatie verstuurt weergegeven als een "Mailable"-klasse. Je genereert de klasse met het Artisan-commando `make:mail`.

```shell theme={null}
php artisan make:mail OrderShipped
```

De gegenereerde klasse wordt geplaatst in de directory `app/Mail/`.

## De Mailable configureren

De gegenereerde Mailable-klasse heeft drie methoden: `envelope()`, `content()` en `attachments()`.

```php theme={null}
<?php

namespace App\Mail;

use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(
        public Order $order,
    ) {}

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Je bestelling is verzonden',
        );
    }

    public function content(): Content
    {
        return new Content(
            view: 'mail.orders.shipped',
        );
    }

    public function attachments(): array
    {
        return [];
    }
}
```

### De afzender instellen

In de methode `envelope()` geef je de afzender op.

```php theme={null}
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;

public function envelope(): Envelope
{
    return new Envelope(
        from: new Address('shop@example.com', 'Shop Support'),
        subject: 'Je bestelling is verzonden',
    );
}
```

Stel je in `config/mail.php` een globaal afzenderadres in, dan kun je de opgave in individuele Mailables achterwege laten.

```php theme={null}
'from' => [
    'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
    'name' => env('MAIL_FROM_NAME', 'Example'),
],
```

### De mailinhoud instellen

In de methode `content()` geef je de Blade-template op. Data die je in de constructor aan `public`-properties toewijst, is automatisch beschikbaar in de template.

```php theme={null}
public function content(): Content
{
    return new Content(
        view: 'mail.orders.shipped',
    );
}
```

Maak de bijbehorende Blade-template aan (`resources/views/mail/orders/shipped.blade.php`).

```blade theme={null}
<!DOCTYPE html>
<html>
<body>
    <h1>Je bestelling is verzonden</h1>
    <p>Bestelnummer: {{ $order->id }}</p>
    <p>Totaalbedrag: ¥{{ number_format($order->total) }}</p>
    <p>Bedankt voor je bestelling.</p>
</body>
</html>
```

Je kunt data ook expliciet doorgeven via de parameter `with`. In dat geval maak je de properties `protected` of `private`.

```php theme={null}
public function __construct(
    protected Order $order,
) {}

public function content(): Content
{
    return new Content(
        view: 'mail.orders.shipped',
        with: [
            'orderId' => $this->order->id,
            'total' => $this->order->total,
        ],
    );
}
```

## E-mail versturen

Met de methode `to()` van de `Mail`-facade geef je de ontvanger op en met `send()` verstuur je de e-mail.

```mermaid theme={null}
flowchart TD
    A["Mail::to()->send(new OrderShipped())"] --> B{"Implementeert<br>ShouldQueue?"}
    B -- "No" --> C["Synchroon versturen<br>naar de mailer"]
    B -- "Yes" --> D["In de queue plaatsen<br>versturen op de achtergrond"]
    D --> C
    C --> E{"MAIL-driver"}
    E --> F["smtp"]
    E --> G["ses / mailgun<br>/ postmark"]
    E --> H["log<br>(voor ontwikkeling)"]
```

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Mail\OrderShipped;
use App\Models\Order;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class OrderShipmentController extends Controller
{
    public function store(Request $request): RedirectResponse
    {
        $order = Order::findOrFail($request->order_id);

        Mail::to($request->user())->send(new OrderShipped($order));

        return redirect('/orders');
    }
}
```

Je kunt ook CC en BCC opgeven.

```php theme={null}
Mail::to($request->user())
    ->cc($ccUsers)
    ->bcc($bccUsers)
    ->send(new OrderShipped($order));
```

Om via een specifieke mailer te versturen gebruik je de methode `mailer()`.

```php theme={null}
Mail::mailer('postmark')
    ->to($request->user())
    ->send(new OrderShipped($order));
```

## E-mail versturen via de queue

Omdat het versturen van e-mail de responstijd beïnvloedt, wordt aanbevolen om via de queue op de achtergrond te versturen.

```php theme={null}
Mail::to($request->user())->queue(new OrderShipped($order));
```

<Warning>
  Om de queue te gebruiken moet je vooraf de queue configureren en een worker starten.
</Warning>

Vertraagd versturen kan ook.

```php theme={null}
Mail::to($request->user())
    ->later(now()->plus(minutes: 10), new OrderShipped($order));
```

Implementeert de Mailable-klasse `ShouldQueue`, dan gaat de e-mail altijd de queue in, ook als je `send()` aanroept.

```php theme={null}
use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Mailable implements ShouldQueue
{
    // ...
}
```

### De queueverbinding en queuenaam opgeven met PHP-attributen

Met PHP-attributen geef je de queueverbinding en queuenaam direct op de Mailable-klasse op. In plaats van de methodchain `on()->queue()` kun je dit declaratief op klasseniveau instellen.

```php theme={null}
use Illuminate\Queue\Attributes\Connection;
use Illuminate\Queue\Attributes\Queue;

#[Connection('sqs')]
#[Queue('emails')]
class OrderShipped extends Mailable implements ShouldQueue
{
    // ...
}
```

Op deze manier maak je in de klassedefinitie expliciet dat deze Mailable altijd naar de `emails`-queue van de SQS-verbinding wordt gestuurd.

## Markdown-mails maken

Met e-mails in Markdown-formaat profiteer je van de fraaie, responsive HTML-templates die Laravel meelevert.

### Een Markdown-Mailable genereren

Genereer de Mailable met de optie `--markdown`.

```shell theme={null}
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
```

In de methode `content()` gebruik je de parameter `markdown`.

```php theme={null}
use Illuminate\Mail\Mailables\Content;

public function content(): Content
{
    return new Content(
        markdown: 'mail.orders.shipped',
        with: [
            'url' => route('orders.show', $this->order),
        ],
    );
}
```

### De Markdown-template schrijven

Je stelt de mailinhoud samen met de Blade-componenten die Laravel meelevert.

```blade theme={null}
<x-mail::message>
# Je bestelling is verzonden

Hierbij laten we je weten dat je bestelling is verzonden.

<x-mail::button :url="$url">
Bestelling bekijken
</x-mail::button>

Bedankt voor je bestelling.<br>
{{ config('app.name') }}
</x-mail::message>
```

De beschikbare componenten zijn als volgt.

| Component          | Beschrijving                                                           |
| ------------------ | ---------------------------------------------------------------------- |
| `<x-mail::button>` | Knoplink (voor `color` kun je `primary`, `success` of `error` opgeven) |
| `<x-mail::panel>`  | Opvallend paneelgebied                                                 |
| `<x-mail::table>`  | Tabel in Markdown-formaat                                              |

<Tip>
  Van Markdown-mails wordt automatisch ook een platte-tekstversie gegenereerd. Zo zijn ze ook leesbaar in mailclients die geen HTML-mail ondersteunen.
</Tip>

## E-mails previewen

Geef je in een route een Mailable-instantie terug, dan kun je de e-mail in de browser previewen. Handig om te controleren tijdens de ontwikkeling.

```php theme={null}
// routes/web.php
Route::get('/mailable', function () {
    $order = App\Models\Order::first();
    return new App\Mail\OrderShipped($order);
});
```

## E-mail tijdens lokale ontwikkeling

Om te voorkomen dat je per ongeluk e-mails in productie verstuurt, is het handig om bij lokale ontwikkeling tools als [Mailpit](https://github.com/axllent/mailpit) te gebruiken.

```ini theme={null}
# .env (Mailpit)
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
```

In `Laragon` en `Laravel Herd` is Mailpit standaard inbegrepen.

<Info>
  Met de `log`-driver wordt de inhoud van e-mails vastgelegd in het logbestand. Wil je alleen controleren dat er e-mail wordt verstuurd, dan is dit de eenvoudigste methode.
</Info>

```ini theme={null}
MAIL_MAILER=log
```

## Samenvatting

| Wat je wilt doen                | Hoe                                     |
| ------------------------------- | --------------------------------------- |
| Een Mailable aanmaken           | `php artisan make:mail ClassName`       |
| De afzender instellen           | De parameter `from` van `envelope()`    |
| Een Blade-template gebruiken    | De parameter `view` van `content()`     |
| Een Markdown-template gebruiken | De parameter `markdown` van `content()` |
| E-mail versturen                | `Mail::to()->send()`                    |
| Versturen via de queue          | `Mail::to()->queue()`                   |
| Vertraagd versturen             | `Mail::to()->later()`                   |


## Related topics

- [Notificaties (Notifications)](/nl/notifications.md)
- [Taakplanning](/nl/scheduling.md)
- [Laravel Console Starter](/nl/packages/laravel-console-starter/index.md)
- [Mocking](/nl/mocking.md)
- [Queues en jobs](/nl/queues.md)
