Back to symfony.com

Demo 6 of 10 · 2 min

Click any paragraph or press to highlight its code

Sending emails

Emails are built with a fluent API and designed with regular Twig templates: your layout, your variables, your logic. No string concatenation, no separate templating system.

The template is plain Twig, so it can reuse anything from your app: routes, translations, formatting. Symfony can also inline your CSS and embed images for picky email clients.

Where does it go? That's one config line. Swap SMTP for Amazon SES, Mailgun or Postmark by changing the DSN, no code changes. And if Messenger is installed, emails are automatically sent asynchronously: your HTTP response never waits for a mail server.

<?phpnamespace App\Service;use App\Entity\Invoice;use Symfony\Bridge\Twig\Mime\TemplatedEmail;use Symfony\Component\Mailer\MailerInterface;class InvoiceMailer{    public function __construct(        private MailerInterface $mailer,    ) {    }    public function sendReceipt(Invoice $invoice): void    {        $email = (new TemplatedEmail())            ->to($invoice->getCustomerEmail())            ->subject('Your receipt from Acme')            ->htmlTemplate('email/receipt.html.twig')            ->context(['invoice' => $invoice]);        $this->mailer->send($email);    }}
<h1>Thanks for your purchase!</h1><p>    We've received your payment of    <strong>{{ invoice.total }}</strong>.</p><p>    <a href="{{ url('invoice_download', {id: invoice.id}) }}">        Download your invoice (PDF)    </a></p>
$ composer require symfony/mailer# .env: swap providers by changing one line (SMTP, Gmail,# Amazon SES, Mailgun, Postmark, Resend, Brevo, ...)MAILER_DSN=smtp://user:pass@smtp.example.com:465