Passer au contenu principal

La fonctionnalité de mail de Laravel

La fonctionnalité mail est basée sur Symfony Mailer et prend en charge SMTP, Mailgun, Postmark, Resend, Amazon SES, sendmail, etc.
SwiftMailer, utilisé dans les anciennes versions, est abandonné. Depuis Laravel 9, c’est Symfony Mailer.
La configuration se trouve dans config/mail.php. Changez le driver via .env.
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="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"

Créer une classe Mailable

Chaque e-mail est représenté par une classe « Mailable ». Utilisez make:mail.
php artisan make:mail OrderShipped
Le fichier est créé dans app/Mail/.

Configurer un Mailable

La classe générée expose envelope(), content() et attachments().
<?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: 'Votre commande a été expédiée',
        );
    }

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

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

Définir l’expéditeur

Utilisez envelope().
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;

public function envelope(): Envelope
{
    return new Envelope(
        from: new Address('[email protected]', 'Shop Support'),
        subject: 'Votre commande a été expédiée',
    );
}
Vous pouvez également définir un expéditeur global dans config/mail.php, ce qui évite de le préciser dans chaque Mailable.
'from' => [
    'address' => env('MAIL_FROM_ADDRESS', '[email protected]'),
    'name' => env('MAIL_FROM_NAME', 'Example'),
],

Définir le contenu

Dans content(), précisez le template Blade. Les propriétés public définies dans le constructeur sont automatiquement disponibles dans le template.
public function content(): Content
{
    return new Content(
        view: 'mail.orders.shipped',
    );
}
Créez le template resources/views/mail/orders/shipped.blade.php.
<!DOCTYPE html>
<html>
<body>
    <h1>Votre commande a été expédiée</h1>
    <p>N° de commande : {{ $order->id }}</p>
    <p>Montant total : {{ number_format($order->total) }}</p>
    <p>Merci pour votre achat.</p>
</body>
</html>
Vous pouvez aussi passer explicitement les données via with. Les propriétés peuvent alors être protected ou private.
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,
        ],
    );
}

Envoyer un e-mail

Utilisez la façade Mail, indiquez le destinataire avec to() puis send().
<?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');
    }
}
Vous pouvez ajouter des destinataires en CC / BCC.
Mail::to($request->user())
    ->cc($ccUsers)
    ->bcc($bccUsers)
    ->send(new OrderShipped($order));
Pour utiliser un mailer précis :
Mail::mailer('postmark')
    ->to($request->user())
    ->send(new OrderShipped($order));

Envoi via queue

L’envoi d’e-mails influe sur le temps de réponse. Passez par la queue pour l’envoi en arrière-plan.
Mail::to($request->user())->queue(new OrderShipped($order));
Pour utiliser la queue, configurez-la et démarrez les workers au préalable.
Envoi différé :
Mail::to($request->user())
    ->later(now()->plus(minutes: 10), new OrderShipped($order));
Si la classe implémente ShouldQueue, send() la place systématiquement en queue.
use Illuminate\Contracts\Queue\ShouldQueue;

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

Définir connexion et nom de file via attributs PHP

Les attributs PHP permettent de spécifier la connexion et le nom de file directement sur la classe, sans chaîner on()->queue().
use Illuminate\Queue\Attributes\Connection;
use Illuminate\Queue\Attributes\Queue;

#[Connection('sqs')]
#[Queue('emails')]
class OrderShipped extends Mailable implements ShouldQueue
{
    // ...
}
Cela indique explicitement que ce Mailable ira toujours dans la file emails sur la connexion SQS.

Créer un e-mail Markdown

Les e-mails Markdown exploitent le beau template HTML responsive fourni par Laravel.

Générer un Mailable Markdown

Utilisez l’option --markdown.
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
Utilisez markdown dans content().
use Illuminate\Mail\Mailables\Content;

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

Écrire le template Markdown

Utilisez les composants Blade fournis par Laravel.
<x-mail::message>
# Votre commande a été expédiée

Nous vous informons que votre commande a été expédiée.

<x-mail::button :url="$url">
Voir la commande
</x-mail::button>

Merci de votre confiance,<br>
{{ config('app.name') }}
</x-mail::message>
Composants disponibles :
ComposantDescription
<x-mail::button>Bouton (color accepte primary, success, error)
<x-mail::panel>Panneau mis en évidence
<x-mail::table>Table Markdown
Une version texte brut est aussi générée automatiquement pour les clients qui ne prennent pas en charge le HTML.

Prévisualiser les e-mails

Retournez une instance de Mailable depuis une route pour prévisualiser dans le navigateur, très utile en développement.
// routes/web.php
Route::get('/mailable', function () {
    $order = App\Models\Order::first();
    return new App\Mail\OrderShipped($order);
});

E-mails en développement local

Pour éviter d’envoyer des e-mails réels par erreur, utilisez un outil comme Mailpit.
# .env (Mailpit)
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
Laragon et Laravel Herd incluent Mailpit par défaut.
Le driver log écrit le contenu du mail dans les logs. C’est le moyen le plus simple pour vérifier un envoi.
MAIL_MAILER=log

Récapitulatif

ObjectifMéthode
Créer un Mailablephp artisan make:mail ClassName
Définir l’expéditeurfrom dans envelope()
Utiliser un template Bladeview dans content()
Utiliser un template Markdownmarkdown dans content()
EnvoyerMail::to()->send()
Envoyer via queueMail::to()->queue()
Envoi différéMail::to()->later()
Dernière modification le 13 juillet 2026