Provider-Hosted Templates

Florent Blaison Nicolas Grekas
Contributed by Florent Blaison and Nicolas Grekas in #64782 and #65819

Many email providers (Brevo, Mailgun, Mailjet, etc.) include a visual drag-and-drop builder for email templates. This lets non-technical people, such as marketing or support teams, design emails and update their content when needed. However, if your emails use Twig templates stored in your application, those same people can't edit them without asking a developer.

Using templates stored in the provider account solves this problem, but until now Symfony Mailer had no common way to use them. Instead, some bridges relied on special headers (such as templateid in Brevo or X-MJ-TemplateID in Mailjet).

Symfony 8.2 adds a new RemoteTemplateEmail class. Instead of building the email body yourself, you pass the template reference and the variables the provider needs to render it:

1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\Mailer\RemoteTemplateEmail;

$email = new RemoteTemplateEmail()
    ->from('sales@example.com')
    ->to('kevin@example.com')
    ->template('order-confirmation', [
        'firstName' => 'Kevin',
        'orderId' => 4321,
    ])
;

$mailer->send($email);

The template reference is always a string (an ID, UUID, name, or alias, depending on the provider), and each transport converts it to the type expected by its API. Everything else (recipients, attachments, tags, metadata, etc.) works just like a regular Email. You can also set a subject to override the one defined in the template, except with Amazon SES, Mailtrap, and Postmark, which don't support this.

This feature is supported by the API transports of Amazon SES, Brevo, MailerSend, Mailgun, Mailjet, Mailtrap, Mandrill, Postmark, Resend, and SendGrid.

Per-Message Open and Click Tracking

Starfox64 Nicolas Grekas
Contributed by Starfox64 and Nicolas Grekas in #65451

Email open and click tracking is usually a global setting in your provider account, so it applies to all your emails. However, privacy regulations may require asking each user for consent before tracking them. The new TrackingHeader lets you override the provider setting for a single email, and each bridge maps it to the provider's native mechanism:

1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\Mailer\Header\TrackingHeader;
use Symfony\Component\Mime\Email;

$email = new Email()
    ->to($user->getEmail())
    // ...
;

$email->getHeaders()->add(new TrackingHeader(
    $user->hasConsentedToOpenTracking(),
    $user->hasConsentedToClickTracking(),
));

Both arguments are optional. When an argument is null, the provider setting is used for that type of tracking.

If an email doesn't add this header (for example, emails sent by third-party bundles), the provider setting applies. To be on the safe side, use the new tracking option to disable tracking by default for all emails. A header added to an individual email always takes precedence over this option:

1
2
3
4
5
6
# config/packages/mailer.yaml
framework:
    mailer:
        tracking:
            opens: false
            clicks: false

This feature is supported by AhaSend, Azure, Brevo, Infobip, Mailchimp, MailerSend, Mailgun, Mailjet, Postmark, and SendGrid. With other transports, it's sent as a regular X-Track header and has no effect.

Read the Mailer documentation for all the details about these features, including the specific behavior of each provider.

Published in #Living on the edge