Slim 4 - Mailer

Daniel Opitz
Daniel Opitz
11 Apr 2020

Table of contents



This tutorial explains how to integrate and use the Symfony Mailer component for creating and sending emails.


To install the mailer component, run:

composer require symfony/mailer


Emails are delivered via a “transport”. For this tutorial we deliver emails over SMTP.

Only for demonstration purposes I use a free Mailtrap account.

In Mailtrap you can create a forwarding rule to your real inbox. Mailtrap keeps a copy of your message in any case.

Add the email settings to your Slim settings array, e.g config/settings.php:

// E-Mail settings
$settings['smtp'] = [
    // use 'null' for the null adapter
    'type' => 'smtp',
    'host' => '',
    'port' => '25',
    'username' => 'my-username',
    'password' => 'my-secret-password',

Autowire the mailer using MailerInterface:


use Psr\Container\ContainerInterface;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\Transport;
use Slim\App;
use Slim\Factory\AppFactory;

return [

    // ...
    // SMTP transport
    MailerInterface::class => function (ContainerInterface $container) {
        $settings = $container->get('settings')['smtp'];
        // or
        // $settings = $container->get('settings')['smtp'];
        // smtp://
        $dsn = sprintf(

        return new Mailer(Transport::fromDsn($dsn));

If you don’t use the Configuration class, just use settings as container entry:

$settings = $container->get('settings')['smtp'];

Creating and Sending Messages

Let the DIC inject the MailerInterface object and create an new Email object:


namespace App\Domain\User\Service;

use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;

final class ContactMailer
     * @var MailerInterface
    private $mailer;

    public function __construct(MailerInterface $mailer)
        $this->mailer = $mailer;

    public function sendEmail(array $formData): void
        // Validate form data

        // Send email
        $email = (new Email())
            ->subject('Time for Symfony Mailer!')
            ->text('Sending emails is fun again!')
            ->html('<p>My HTML content</p>');


    private function validate(array $data): void
        // ...

Twig Integration

The Twig bridge provides integration for Twig with various Symfony components. To install the Twig Bridge, run:

composer require symfony/twig-bridge

To render Twig templates in emails just add a new container definition for BodyRendererInterface:class in config/container.php

use Symfony\Component\Mime\BodyRendererInterface;
use Slim\Views\Twig;
use Psr\Container\ContainerInterface;
// ...

BodyRendererInterface::class => function(ContainerInterface $container)
    return new BodyRenderer($container->get(Twig::class)->getEnvironment());

To define the contents of your email with Twig, use the TemplatedEmail class (and not the Email class). This class extends the normal Email class but adds some new methods for Twig templates.

Then inject the BodyRendererInterface instance via constructor injection where you need it.


use Symfony\Bridge\Twig\Mime\TemplatedEmail;

$email = (new TemplatedEmail())
    ->to(new Address(''))
    ->subject('Thanks for signing up!')

    // path of the Twig template to render

    // pass variables (name => value) to the template
        'username' => 'foo',

 // Render the email twig template

// Send email

Error handling

To catch all mailer errors, just add a try/catch block around the send method:

try {
} catch (Exception $exception) {
   // handle error here...

Read more