Un formulaire d'inscription, une confirmation de commande, un lien de réinitialisation de mot de passe… presque chaque flux d'une application moderne implique des e-mails. La couche Laravel mail rend la tâche bien moins intimidante qu'on ne le croit : les classes Mailable représentent un seul e-mail, tandis que les classes Notification permettent de diffuser le même message sur plusieurs canaux à la fois, comme le mail, la base de données et Slack. Dans ce guide, nous verrons quand utiliser chacun, comment concevoir vos modèles et comment fiabiliser l'envoi.
Configurer SMTP et choisir un pilote
Tout commence dans config/mail.php et .env. Laravel prend en charge des pilotes comme SMTP, Amazon SES, Postmark, Mailgun et log. Pendant le développement, le pilote log écrit les messages dans storage/logs/laravel.log, ce qui permet d'inspecter la sortie sans envoyer de vrais e-mails.
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}"
Pour les tests locaux, un outil comme Mailpit ou Mailtrap est précieux : chaque e-mail sortant est capturé dans une boîte web et rien n'atteint de vrais utilisateurs.
Votre premier Mailable
Générez avec Artisan une classe représentant un seul e-mail. L'option --markdown crée un modèle prêt à l'emploi :
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
Depuis Laravel 9, le Mailable est divisé en trois méthodes : envelope() (sujet, expéditeur), content() (vue et données) et attachments(). Le résultat est clair et facile à lire :
class OrderShipped extends Mailable
{
use Queueable, SerializesModels;
public function __construct(public Order $order) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Votre commande est en route',
);
}
public function content(): Content
{
return new Content(
markdown: 'mail.orders.shipped',
with: ['order' => $this->order],
);
}
}
L'envoi ne demande que la façade Mail :
use Illuminate\Support\Facades\Mail;
Mail::to($order->user)->send(new OrderShipped($order));
Concevoir avec les modèles Markdown
Les mailables Markdown utilisent les composants préconçus de Laravel et génèrent automatiquement une version HTML et une version texte brut. Le modèle est livré avec un thème propre et responsive :
<x-mail::message>
# Bonjour {{ $order->user->name }}
Votre commande ({{ $order->number }}) a été expédiée.
<x-mail::button :url="$url">
Voir la commande
</x-mail::button>
Merci,<br>
{{ config('app.name') }}
</x-mail::message>
Pour adapter le thème à votre marque, exécutez php artisan vendor:publish --tag=laravel-mail afin de publier les composants et le fichier resources/css/mail.css. Vous y modifiez les couleurs, le logo et le pied de page.
Diffusion multicanal avec les Notifications
Quand vous voulez annoncer le même événement sur plus d'un canal, Notification prend le relais. Par exemple, lorsqu'une facture est payée, vous pouvez envoyer un e-mail et aussi enregistrer une entrée en base de données.
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('Votre facture a été payée')
->greeting('Bonjour !')
->line('Votre facture de '.$this->invoice->amount.' a été payée.')
->action('Voir la facture', url('/invoices/'.$this->invoice->id))
->line('Merci.');
}
public function toArray(object $notifiable): array
{
return ['invoice_id' => $this->invoice->id];
}
}
Si votre modèle utilise le trait Notifiable, l'envoi tient en une ligne :
$user->notify(new InvoicePaid($invoice));
Si vous utilisez le canal database dans via(), n'oubliez pas de créer la table avec php artisan make:notifications-table. À côté des canaux officiels comme Slack, SMS (Vonage) et broadcast, des paquets communautaires ajoutent Telegram ou WhatsApp.
Mise en file d'attente et gestion des erreurs
Envoyer un e-mail est une opération lente ; ne faites pas attendre l'utilisateur pour une réponse SMTP. Implémenter l'interface ShouldQueue place automatiquement le mail ou la notification dans la file :
class OrderShipped extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
// ...
}
Un worker est nécessaire pour exécuter la file : php artisan queue:work. En production, gardez-le actif avec Supervisor. Les jobs échoués atterrissent dans la table failed_jobs et peuvent être relancés avec php artisan queue:retry. Pour les erreurs SMTP transitoires, vous pouvez définir $tries et une méthode backoff() sur le Mailable afin de contrôler les intervalles de nouvelle tentative.
Tester
Vous n'avez pas besoin d'un vrai SMTP pour tester l'envoi. Mail::fake() intercepte l'envoi afin de pouvoir le vérifier :
Mail::fake();
// ... traiter la commande ...
Mail::assertSent(OrderShipped::class, function ($mail) use ($order) {
return $mail->order->id === $order->id;
});
De même, Notification::fake() et Notification::assertSentTo() permettent de tester les notifications. Cette approche garde vos tests rapides et indépendants des services externes.
Questions fréquentes
Dois-je utiliser un Mailable ou une Notification ?
Si vous envoyez un message riche et au design personnalisé via un seul canal (e-mail uniquement), un Mailable suffit. Si vous voulez diffuser le même événement sur plusieurs canaux (mail + base de données + Slack) ou laisser l'utilisateur choisir ses canaux, une Notification convient mieux.
Pourquoi mes e-mails partent-ils en retard ou pas du tout ?
La cause la plus fréquente est d'utiliser ShouldQueue sans lancer de worker. Vérifiez que queue:work tourne, inspectez la table failed_jobs et storage/logs, et contrôlez vos identifiants SMTP et le port.
Comment éviter que les e-mails HTML tombent dans le spam ?
Un domaine d'envoi vérifié, des enregistrements SPF/DKIM/DMARC et une alternative en texte brut donnent les résultats les plus fiables. Les mailables Markdown génèrent déjà la version texte ; privilégiez aussi un fournisseur de réputation solide comme SES, Postmark ou Mailgun.
Vous souhaitez construire votre flux d'e-mails de zéro ou assainir un système de notifications existant ? Concevons ensemble la pile Laravel mail et notification autour de vos besoins. Contactez-moi.