Aller au contenu principal
Retour au blog

Tracking des emails Symfony 8.2 : TrackingHeader par message

Symfony 8.2 Mailer : TrackingHeader pour activer ouvertures et clics email par email selon le consentement, tracking coupé par défaut et templates hébergés.

Flavien Métivier · 10 min de lecture
Sommaire · 7 parties

Le TrackingHeader est un en-tête de Symfony 8.2 qui active ou désactive, pour un seul email, le suivi des ouvertures et des clics du fournisseur. Une nouvelle option framework.mailer.tracking permet de couper ce suivi par défaut, et le même cycle livre une API commune pour les templates hébergés chez le fournisseur. Présentées le 24 septembre 2026 sur le blog officiel (PR #65451 de Starfox64 et Nicolas Grekas pour le tracking, #64782 et #65819 pour les templates), ces nouveautés arrivent avec Symfony 8.2, attendu en novembre 2026.

Ton fournisseur pose ses pixels d'ouverture et réécrit tes liens pour mesurer les clics. En général, c'est un réglage global du compte, activé une fois, et personne n'y retouche. Or le billet le rappelle : les règles de vie privée peuvent exiger de demander le consentement de chaque utilisateur avant de le suivre. Jusqu'ici, tenir cette promesse voulait dire connaître le mécanisme propre à chaque fournisseur : un paramètre d'API chez l'un, un en-tête maison chez l'autre, rien du tout chez le troisième.

Pourquoi contrôler le tracking des emails message par message ?

Un réglage global ne distingue pas l'utilisateur qui a consenti de celui qui a refusé. La PR #65451 cite d'ailleurs la CNIL comme motivation : les utilisateurs doivent pouvoir refuser le suivi, ce qui suppose un contrôle par destinataire, indépendant du fournisseur. Restons factuels : c'est l'intention des contributeurs, pas une analyse juridique, et le billet ne dit nulle part que cet en-tête rend ton application conforme. C'est un levier technique ; la conformité, elle, relève de ton DPO.

TrackingHeader : activer ouvertures et clics email par email

Tu poses l'en-tête sur l'email, avec deux arguments, et chaque bridge le traduit vers le mécanisme natif de son fournisseur. Exemple du billet :

php
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(),
));

Les deux arguments sont optionnels, et null signifie « appliquer le réglage du fournisseur pour ce type de suivi ». Attention, null n'est pas false : un booléen force un état, null laisse décider le fournisseur. Les méthodes hasConsentedTo…() de l'exemple sont fictives : le recueil et la conservation du consentement restent à ta charge. L'en-tête est résolu par son nom, X-Track, ce qui lui permet de survivre à une sérialisation, par exemple quand le message transite par Messenger.

Désactiver le tracking par défaut avec framework.mailer.tracking

Un en-tête posé message par message ne protège que les emails que tu as écrits toi-même. Les emails émis par des bundles tiers (réinitialisation de mot de passe, notifications) ne l'ajoutent pas, et le réglage du fournisseur s'applique, souvent « tout activé ». La nouvelle option inverse ce défaut :

yaml
# config/packages/mailer.yaml
framework:
    mailer:
        tracking:
            opens: false
            clicks: false

Un en-tête ajouté à un email l'emporte toujours sur l'option framework.mailer.tracking. La précédence complète, de la plus forte à la plus faible :

  • le TrackingHeader posé sur le message ;
  • une entrée X-Track dans framework.mailer.headers ;
  • l’option framework.mailer.tracking ;
  • le réglage du fournisseur.

Au-dessus de cette chaîne, un en-tête ou un réglage propre à un fournisseur l'emporte toujours sur le mécanisme portable. Le schéma qui en découle est du privacy by default : tout est coupé, et seul l'utilisateur ayant consenti reçoit un TrackingHeader à true. C'est mon interprétation de la fonctionnalité, pas un pattern documenté, mais elle me paraît être le bon usage. Sur le même registre de protection des données, voir le chiffrement applicatif avec KeyManagement.

Quels fournisseurs respectent le TrackingHeader ?

Migration Symfony en vue ?

Bear Upgrade migre votre codebase 2,5× à 4,5× moins cher qu'une ESN, selon sa maturité.

Estimer ma migration →

D’après le billet, le contrôle par message est supporté par :

  • AhaSend
  • Azure
  • Brevo
  • Infobip
  • Mailchimp (Mandrill)
  • MailerSend
  • Mailgun
  • Mailjet
  • Postmark
  • SendGrid

Avec un transport non supporté, le TrackingHeader part en X-Track sans aucun effet, sans erreur ni avertissement. Selon la PR, Resend et Mailtrap règlent le suivi au niveau du domaine, Amazon SES passe par ses configuration sets, et MailPace ne fait pas de suivi. Trois autres subtilités : Azure et Brevo fusionnent les deux drapeaux en un seul contrôle, Brevo anonymise au lieu de désactiver, et certains bridges (Azure, Brevo, MailerSend) ne gèrent l'en-tête qu'en API, pas en SMTP. Si le « zéro suivi » compte pour toi, vérifie sur un envoi réel : relis le HTML reçu, cherche le pixel et les liens réécrits.

Templates hébergés chez le fournisseur : rappel

La 8.2 ajoute aussi RemoteTemplateEmail, pour envoyer un email à partir d'un template conçu dans l'éditeur du fournisseur, que le marketing modifie sans développeur. Je l'ai déjà détaillé dans notre article sur RemoteTemplateEmail et le transport Microsoft Graph ; voici l'essentiel. Exemple du billet, avec la syntaxe new X()->… de PHP 8.4 :

php
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);
  • Les transports API supportés sont Amazon SES, Brevo, MailerSend, Mailgun, Mailjet, Mailtrap, Mandrill, Postmark, Resend et SendGrid. Ce n’est pas la même liste que pour le tracking : choisis ton fournisseur en tenant compte des deux.
  • Un seul jeu de variables par message ; le sujet est surchargeable, sauf avec SES, Mailtrap et Postmark, qui lèvent une exception.
  • Brevo et Mailjet n’acceptent que des identifiants numériques.
  • Les en-têtes magiques sont dépréciés : templateid et params chez Brevo, template nu chez Mailgun, X-MJ-TemplateID chez Mailjet.
  • Envoyé vers SMTP ou un bridge non migré, un RemoteTemplateEmail lève une LogicException, qui n’est pas une exception de transport : un failover ne bascule pas sur le transport suivant.

Checklist avant la montée en 8.2

  • Pose framework.mailer.tracking à false pour les ouvertures et les clics.
  • Lis le consentement depuis ton modèle utilisateur et ajoute un TrackingHeader à true uniquement pour ceux qui l’ont donné.
  • Vérifie que ton fournisseur et ton schéma de DSN (API ou SMTP) figurent dans la liste supportée, sinon règle le suivi côté fournisseur.
  • Teste les deux chemins, avec et sans consentement, et inspecte les emails reçus.
  • Migre les en-têtes magiques de templates vers RemoteTemplateEmail, et vérifie que tous les transports d’une chaîne de failover supportent les templates.

Que retenir de Symfony 8.2 ?

Active tracking: { opens: false, clicks: false } dès que tu passes en 8.2 : le suivi devient une exception accordée par consentement, plus un défaut subi. Puis teste ton bridge réel, parce qu'un en-tête sans effet reste silencieux, et qu'en cas de contrôle, « le framework disait de ne pas suivre » ne sert à rien.

Cet article clôt notre série : 22 nouveautés de Symfony 8.2, une par article, depuis le découpage de FrameworkBundle en 29 bundles jusqu'au Mailer. Aucune n'est spectaculaire seule, mais ensemble elles changent des comportements par défaut, du Mailer à la sécurité en passant par Messenger et la configuration. La version stable est attendue fin novembre ; d'ici là, des détails peuvent encore bouger. Relis la documentation officielle de chaque fonctionnalité avant de t'appuyer dessus en production, surtout pour les API marquées expérimentales.

Avant la sortie, passe en revue ce qui, dans ton application, repose sur ces comportements : en-têtes propres à un fournisseur, emails envoyés par des bundles tiers, dépréciations restées en suspens. Si tu préfères ne pas faire ce tri seul, Bear Upgrade prépare et réalise cette montée de version sur ton code, avec Rector, des tests et des Merge Requests prêtes à relire.

Cet article vous a été utile ? Partagez-le.

Portrait de Flavien Métivier, fondateur de The Bearded Bear : barbe longue, lunettes, sur fond sombre

Écrit par

Flavien Métivier

Expert PHP/Symfony indépendant depuis 2014, ancien CTO de Kartable et d'Extrabat. Plus de 80 projets menés, de l'audit à la migration.

Mon parcours

À lire ensuite

Migration Symfony en vue ?

Bear Upgrade migre votre codebase 2,5× à 4,5× moins cher qu'une ESN, selon sa maturité.

Newsletter Bear Bytes

Veille Claude Code, Symfony et PHP, retours d'expérience terrain et conseils techniques, directement dans votre boîte mail.