Een aanmeldformulier, een orderbevestiging, een link om je wachtwoord te resetten… vrijwel elke flow in een moderne applicatie heeft met e-mail te maken. De Laravel mail-laag maakt dit een stuk minder ontmoedigend dan je zou denken: Mailable-klassen vertegenwoordigen één e-mail, terwijl Notification-klassen het mogelijk maken hetzelfde bericht tegelijk via meerdere kanalen te versturen, zoals mail, de database en Slack. In deze gids bekijken we wanneer je elk gebruikt, hoe je je templates ontwerpt en hoe je de bezorging betrouwbaar maakt.
SMTP configureren en een driver kiezen
Alles begint in config/mail.php en .env. Laravel ondersteunt drivers zoals SMTP, Amazon SES, Postmark, Mailgun en log. Tijdens de ontwikkeling schrijft de log-driver berichten naar storage/logs/laravel.log, zodat je de uitvoer kunt bekijken zonder echte mail te versturen.
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@example.com
MAIL_PASSWORD=secret
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
Voor lokaal testen is een tool als Mailpit of Mailtrap onmisbaar: elke uitgaande e-mail wordt opgevangen in een webinbox en niets bereikt echte gebruikers.
Je eerste Mailable
Genereer met Artisan een klasse die één e-mail vertegenwoordigt. De vlag --markdown maakt meteen een kant-en-klare template:
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
Sinds Laravel 9 is de Mailable opgesplitst in drie methoden: envelope() (onderwerp, afzender), content() (view en data) en attachments(). Het resultaat is helder en goed leesbaar:
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public Order $order) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Je bestelling is onderweg',
);
}
public function content(): Content
{
return new Content(
markdown: 'mail.orders.shipped',
with: ['order' => $this->order],
);
}
}
Versturen vereist alleen de Mail-facade:
use Illuminate\Support\Facades\Mail;
Mail::to($order->user)->send(new OrderShipped($order));
Ontwerpen met Markdown-templates
Markdown-mailables gebruiken de voorgebouwde componenten van Laravel en renderen automatisch zowel een HTML- als een platte-tekstversie. De template komt met een nette, responsieve stijl:
<x-mail::message>
# Hallo {{ $order->user->name }}
Je bestelling ({{ $order->number }}) is verzonden.
<x-mail::button :url="$url">
Bestelling bekijken
</x-mail::button>
Bedankt,<br>
{{ config('app.name') }}
</x-mail::message>
Om de stijl op je merk af te stemmen, voer je php artisan vendor:publish --tag=laravel-mail uit om de componenten en het bestand resources/css/mail.css te publiceren. Daar pas je kleuren, het logo en de footer aan.
Multichannel-bezorging met Notifications
Wil je dezelfde gebeurtenis via meer dan één kanaal aankondigen, dan neemt Notification het over. Wanneer een factuur bijvoorbeeld is betaald, wil je misschien een e-mail sturen en ook een record in de database wegschrijven.
php artisan make:notification InvoicePaid
class InvoicePaid extends Notification
{
use Queueable;
public function __construct(public Invoice $invoice) {}
public function via(object $notifiable): array
{
return ['mail', 'database'];
}
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->subject('Je factuur is betaald')
->greeting('Hallo!')
->line('Je factuur van '.$this->invoice->amount.' is betaald.')
->action('Factuur bekijken', url('/invoices/'.$this->invoice->id))
->line('Bedankt.');
}
public function toArray(object $notifiable): array
{
return ['invoice_id' => $this->invoice->id];
}
}
Gebruikt je model de Notifiable-trait, dan is versturen één regel:
$user->notify(new InvoicePaid($invoice));
Gebruik je het database-kanaal in via(), vergeet dan niet de tabel aan te maken met php artisan make:notifications-table. Naast officiële kanalen als Slack, SMS (Vonage) en broadcast voegen community-pakketten Telegram of WhatsApp toe.
In de wachtrij zetten en foutafhandeling
E-mail versturen is traag werk; laat de gebruiker niet wachten op een SMTP-antwoord. De interface ShouldQueue implementeren plaatst de mail of notification automatisch in de wachtrij:
class OrderShipped extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
// ...
}
Voor het draaien van de wachtrij is een worker nodig: php artisan queue:work. Houd deze in productie draaiend met Supervisor. Mislukte jobs komen in de tabel failed_jobs en kun je opnieuw uitvoeren met php artisan queue:retry. Voor tijdelijke SMTP-fouten kun je $tries en een backoff() op de Mailable definiëren om de intervallen voor opnieuw proberen te regelen.
Testen
Je hebt geen echte SMTP nodig om versturen te testen. Mail::fake() onderschept de bezorging zodat je erop kunt asserten:
Mail::fake();
// ... verwerk de bestelling ...
Mail::assertSent(OrderShipped::class, function ($mail) use ($order) {
return $mail->order->id === $order->id;
});
Op dezelfde manier kun je met Notification::fake() en Notification::assertSentTo() notifications testen. Deze aanpak houdt je tests snel en onafhankelijk van externe services.
Veelgestelde vragen
Moet ik een Mailable of een Notification gebruiken?
Stuur je een rijk, maatwerkbericht via één kanaal (alleen e-mail), dan is een Mailable voldoende. Wil je dezelfde gebeurtenis via meerdere kanalen leveren (mail + database + Slack) of de gebruiker zijn kanalen laten kiezen, dan past een Notification beter.
Waarom worden mijn e-mails te laat of helemaal niet verzonden?
De meest voorkomende oorzaak is ShouldQueue gebruiken zonder een worker te draaien. Controleer of queue:work loopt, bekijk de tabel failed_jobs en storage/logs, en verifieer je SMTP-gegevens en poortinstellingen.
Hoe houd ik HTML-e-mails uit de spam?
Een geverifieerd verzenddomein, SPF/DKIM/DMARC-records en een platte-tekstalternatief geven de meest betrouwbare resultaten. Markdown-mailables genereren de platte-tekstversie al; kies daarnaast een aanbieder met een goede reputatie zoals SES, Postmark of Mailgun.
Wil je je e-mailflow vanaf nul opbouwen of een bestaand notificatiesysteem opschonen? Laten we de Laravel mail- en notification-stack rond jouw behoeften ontwerpen. Neem contact met me op.