Zum Hauptinhalt springen

Was ist die E-Mail-Funktion von Laravel

Die E-Mail-Funktion von Laravel basiert auf dem Symfony Mailer und unterstützt Treiber wie SMTP, Mailgun, Postmark, Resend, Amazon SES und sendmail.
Der früher in Laravel eingesetzte SwiftMailer ist veraltet. Seit Laravel 9 wird der Symfony Mailer verwendet.
Die E-Mail-Konfiguration wird in config/mail.php verwaltet. Über die .env-Datei können Sie den verwendeten Treiber wechseln.
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}"

Eine Mailable-Klasse erstellen

In Laravel wird jede E-Mail, die die Anwendung versendet, als „Mailable“-Klasse dargestellt. Mit dem Artisan-Befehl make:mail erzeugen Sie eine solche Klasse.
php artisan make:mail OrderShipped
Die generierte Klasse wird im Verzeichnis app/Mail/ abgelegt.

Mailable konfigurieren

Die generierte Mailable-Klasse besitzt die drei Methoden envelope(), content() und 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: 'Ihre Bestellung wurde versendet',
        );
    }

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

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

Absender konfigurieren

Über die Methode envelope() können Sie den Absender angeben.
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: 'Ihre Bestellung wurde versendet',
    );
}
Wenn Sie in config/mail.php eine globale Absenderadresse hinterlegen, können Sie die Angabe in jeder einzelnen Mailable weglassen.
'from' => [
    'address' => env('MAIL_FROM_ADDRESS', '[email protected]'),
    'name' => env('MAIL_FROM_NAME', 'Example'),
],

E-Mail-Inhalt konfigurieren

Über die Methode content() geben Sie das Blade-Template an. Daten, die Sie im Konstruktor als public-Eigenschaft setzen, stehen automatisch im Template zur Verfügung.
public function content(): Content
{
    return new Content(
        view: 'mail.orders.shipped',
    );
}
Erstellen Sie das zugehörige Blade-Template (resources/views/mail/orders/shipped.blade.php).
<!DOCTYPE html>
<html>
<body>
    <h1>Ihre Bestellung wurde versendet</h1>
    <p>Bestellnummer: {{ $order->id }}</p>
    <p>Gesamtbetrag: €{{ number_format($order->total, 2, ',', '.') }}</p>
    <p>Vielen Dank für Ihre Bestellung.</p>
</body>
</html>
Sie können die Daten auch explizit über den Parameter with übergeben. In diesem Fall sollten die Eigenschaften protected oder private sein.
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-Mails versenden

Geben Sie den Empfänger mit der to()-Methode der Mail-Fassade an und versenden Sie die Mail mit 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');
    }
}
CC und BCC können ebenfalls angegeben werden.
Mail::to($request->user())
    ->cc($ccUsers)
    ->bcc($bccUsers)
    ->send(new OrderShipped($order));
Um über einen bestimmten Mailer zu versenden, verwenden Sie die Methode mailer().
Mail::mailer('postmark')
    ->to($request->user())
    ->send(new OrderShipped($order));

E-Mail-Versand über Queues

Da der E-Mail-Versand die Antwortzeit beeinflusst, empfiehlt es sich, ihn über eine Queue im Hintergrund abzuwickeln.
Mail::to($request->user())->queue(new OrderShipped($order));
Für die Nutzung von Queues muss die Queue-Konfiguration eingerichtet und ein Worker gestartet sein.
Auch ein verzögerter Versand ist möglich.
Mail::to($request->user())
    ->later(now()->plus(minutes: 10), new OrderShipped($order));
Wenn Sie in der Mailable-Klasse ShouldQueue implementieren, wird die Mail auch bei einem Aufruf von send() immer in die Queue eingereiht.
use Illuminate\Contracts\Queue\ShouldQueue;

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

Queue-Verbindung und Queue-Name per PHP-Attribut angeben

Mit PHP-Attributen können Sie Queue-Verbindung und Queue-Name direkt an der Mailable-Klasse festlegen. Statt der Methoden-Kette on()->queue() konfigurieren Sie diese Werte deklarativ auf Klassenebene.
use Illuminate\Queue\Attributes\Connection;
use Illuminate\Queue\Attributes\Queue;

#[Connection('sqs')]
#[Queue('emails')]
class OrderShipped extends Mailable implements ShouldQueue
{
    // ...
}
So machen Sie in der Klassendefinition deutlich, dass diese Mailable stets an die Queue emails auf der SQS-Verbindung übergeben wird.

Markdown-Mails erstellen

Mit Markdown-Mails können Sie die von Laravel bereitgestellten, schönen und responsiven HTML-Templates nutzen.

Markdown-Mailable erzeugen

Erzeugen Sie das Mailable mit der Option --markdown.
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
Verwenden Sie in der Methode content() den Parameter markdown.
use Illuminate\Mail\Mailables\Content;

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

Markdown-Templates schreiben

Verfassen Sie den E-Mail-Text mithilfe der von Laravel bereitgestellten Blade-Komponenten.
<x-mail::message>
# Ihre Bestellung wurde versendet

wir möchten Sie darüber informieren, dass Ihre Bestellung versendet wurde.

<x-mail::button :url="$url">
Bestellung ansehen
</x-mail::button>

Vielen Dank für Ihre Nutzung.<br>
{{ config('app.name') }}
</x-mail::message>
Die verfügbaren Komponenten sind:
KomponenteBeschreibung
<x-mail::button>Button-Link (für color sind primary, success, error möglich)
<x-mail::panel>Hervorgehobener Panel-Bereich
<x-mail::table>Tabelle im Markdown-Format
Markdown-Mails erzeugen automatisch auch eine reine Textvariante. So können sie auch in E-Mail-Clients gelesen werden, die keine HTML-Mails unterstützen.

E-Mails in der Vorschau anzeigen

Wenn Sie in einer Route eine Mailable-Instanz zurückgeben, können Sie die Mail im Browser als Vorschau ansehen. Das ist während der Entwicklung sehr praktisch.
// routes/web.php
Route::get('/mailable', function () {
    $order = App\Models\Order::first();
    return new App\Mail\OrderShipped($order);
});

E-Mails in der lokalen Entwicklung

Damit in der Produktionsumgebung keine Mails versehentlich versendet werden, ist es hilfreich, für die lokale Entwicklung Tools wie Mailpit einzusetzen.
# .env (Mailpit)
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
In Laragon oder Laravel Herd ist Mailpit standardmäßig enthalten.
Mit dem Treiber log wird der Inhalt der E-Mail in die Logdatei geschrieben. Wenn Sie nur den Versand prüfen möchten, ist dies die einfachste Variante.
MAIL_MAILER=log

Zusammenfassung

ZielVorgehen
Mailable erstellenphp artisan make:mail ClassName
Absender festlegenParameter from in envelope()
Blade-Template verwendenParameter view in content()
Markdown-Template verwendenParameter markdown in content()
E-Mail versendenMail::to()->send()
Mit Queue versendenMail::to()->queue()
Verzögert versendenMail::to()->later()
Zuletzt geändert am 13. Juli 2026