Développeurs
Comment coder un modèle de réception d’email avec MJML et le templating language de Mailjet
La création de reçus électroniques prêts pour la production peut s’avérer difficile, en particulier lorsque vous devez gérer plusieurs scénarios (clients invités ou connectés, différentes méthodes d’expédition, remises et prise en charge de plusieurs devises). Ce guide complet vous montrera comment créer un modèle de réception d’email dynamique en responsive design en utilisant MJML pour la mise en page et le templating language de Mailjet pour la personnalisation de l’email.
À la fin de ce tutoriel, vous disposerez d’un modèle de reçu entièrement fonctionnel, capable de gérer des données de commande complexes, de joindre des factures au format PDF et d’effectuer des livraisons fiables via Send API v3.1 de Mailjet.
Pourquoi utiliser des modèles avec un templating language ?
Avant de passer à la mise en œuvre, il convient de comprendre pourquoi cette approche est supérieure à la création d’emails HTML ponctuels :
- Moins de modèles à gérer : un seul modèle de reçu « intelligent » peut gérer plusieurs scénarios (invités ou utilisateurs connectés, livraison ou enlèvement, remises, multidevises)
- Personnalisation côté serveur : injectez des données dynamiques à l’aide des variables {{var:*}} ou {{data:*}} et contrôlez le rendu à l’aide de conditions et de boucles
- Intégration plus rapide : enregistrez le modèle une fois, puis déclenchez-le avec un seul appel API par commande.
Ce que vous allez concevoir
Votre modèle final de reçu électronique comprendra les éléments suivants :
- Mise en page MJML en responsive design qui fonctionne avec tous les clients de messagerie
- Boucles dynamiques de postes pour les détails de la commande
- Calculs des taxes, des remises et du total
- Affichage conditionnel des informations relatives à l’expédition
- Texte localisé et mise en forme des devises
- Pièces jointes facultatives pour les factures au format PDF
- Livraison fiable grâce à Send API v3.1 de Mailjet avec suivi des événements
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
- Un compte Mailjet avec un domaine d’expéditeur validé (configurer SPF/DKIM pour une délivrabilité optimale)
- Un flux de travail MJML (CLI ou éditeur) pour compiler MJML en HTML
- Identifiants d’API Mailjet (clé API et secret pour HTTP Basic Auth)
- Facultatif : un point de terminaison webhook pour recevoir les événements de livraison (envoyé, ouvert, clic, rebond, etc.).
Étape 1 : Structurez le reçu avec MJML
Commençons par créer la structure de base de notre modèle de reçu à l’aide de MJML. Cela permettra de s’assurer que notre email est en responsive design et qu’il s’affiche de manière cohérente sur les différents clients de messagerie.
<mjml>
<mj-head>
<mj-title>Votre reçu</mj-title>
<mj-attributes>
<mj-text font-family="Montserrat, Arial, sans-serif"></mj-text>
<mj-class name="muted" color="#6b7280" font-size="13px"></mj-class>
<mj-class name="total" font-weight="700" font-size="16px"></mj-class>
</mj-attributes>
</mj-head>
<mj-body background-color="#f6f7fb">
<mj-section background-color="#ffffff" padding="24px">
<mj-column>
<mj-image width="120px" src="https://yourcdn.com/logo.png" alt="Marque"></mj-image>
<mj-text font-size="20px" font-weight="700">Merci pour votre achat !</mj-text>
<mj-text css-class="muted">
Commande {{var:order_id}} • {{var:order_date}} • {{var:currency}}
</mj-text>
<!-- Shipping notice (rendered conditionally in Step 2) -->
<mj-text css-class="muted">
Livraison à : {{var:shipping.name}}, {{var:shipping.address1}}, {{var:shipping.city}}
</mj-text>
<mj-divider border-color="#e5e7eb"></mj-divider>
<!-- Line items table (rendered via loop in Step 2) -->
<mj-table>
<tr style="text-align:left;">
<th style="padding:8px 0;">Article</th>
<th style="padding:8px 0;">Qté</th>
<th style="padding:8px 0; text-align:right;">Tarifs</th>
</tr>
<!-- row loop here -->
</mj-table>
<mj-divider border-color="#e5e7eb"></mj-divider>
<mj-text>
Sous-total <span style="float:right;">{{var:money.subtotal}}</span>
</mj-text>
<mj-text>
Taxes <span style="float:right;">{{var:money.tax}}</span>
</mj-text>
{{var:money.discount_row}} <!-- optional discount row via condition -->
<mj-text css-class="total">
Total <span style="float:right;">{{var:money.total}}</span>
</mj-text>
<mj-divider border-color="#e5e7eb"></mj-divider>
<mj-text css-class="muted">
Payé avec {{var:payment.brand}} se terminant par {{var:payment.last4}}. Besoin d'un PDF ? Il est joint.
</mj-text>
<mj-text css-class="muted">
Des questions ? Répondez à cet email ou visitez votre page de commande : {{var:order_url}}
</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-text css-class="muted" align="center">
© {{var:year}} Votre entreprise • {{var:support_email}}
</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
Remarques importantes :
- Conservez le format des devises côté serveur et passez des chaînes prêtes à être rendues (money.*) pour éviter les incohérences de localisation
- MJML se compile en HTML en responsive design qui fonctionne avec les principaux clients de messagerie.
Étape 2 : Ajoutez les balises de modèle Mailjet
Nous allons maintenant améliorer notre modèle avec le templating language de Mailjet pour gérer le contenu dynamique. Il s’agit des variables, des conditions et des boucles qui seront traitées lors de l’envoi de l’email.
Types de variables
Le templating language de Mailjet prend en charge plusieurs types de variables :
- Variables de commande : {{var:order_id}}, {{var:currency}}, {{var:payment.brand}}
- Données de contact : {{data:firstname:"Client"}} (avec valeurs alternatives)
- Conditions : {% if var:has_shipping %} … {% endif %}
- Boucles : {% for item in var:items %} … {% endfor %}
Ajout de postes dynamiques
Insérez ce code dans votre table MJML pour parcourir en boucle les articles de la commande :
{% for item in var:items %}
<tr>
<td style="padding:6px 0;">{{item.name}}</td>
<td style="padding:6px 0;">{{item.qty}}</td>
<td style="padding:6px 0; text-align:right;">{{item.price}}</td>
</tr>
{% endfor %}
Informations conditionnelles sur la livraison
Ajoutez des blocs conditionnels pour n’afficher les détails de livraison que lorsque cela est pertinent :
{% if var:has_shipping %}
<mj-text css-class="muted">
Livraison à : {{var:shipping.name}}, {{var:shipping.address1}}, {{var:shipping.city}}
</mj-text>
{% endif %}
Étape 3 : Enregistrez le code HTML en tant que modèle réutilisable
Une fois que vous avez compilé votre MJML en HTML et ajouté des balises de modélisation, vous devez l’enregistrer en tant que modèle dans Mailjet. Deux possibilités s’offrent à vous :
Option A : Utiliser le tableau de bord Mailjet
Collez votre code HTML compilé dans un nouveau modèle dans l’application Mailjet (Passport).
Option B : Utilisation de l’API des modèles
Créer un modèle :
curl -s -X POST \
--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
https://api.mailjet.com/v3/REST/template \
-H 'Content-Type: application/json' \
-d '{
"Name":"Receipt v1",
"OwnerType":"user",
"IsTextPartGenerationEnabled":"true",
"Locale":"en_US"
}'
Ajoutez votre contenu HTML au modèle :
curl -s -X POST \
--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
https://api.mailjet.com/v3/REST/template/TEMPLATE_ID/detailcontent \
-H 'Content-Type: application/json' \
-d '{
"Html-part":"...votre MJML compilé avec des balises de modélisation...",
"Text-part":"Votre texte alternatif au format brut"
}'
Étape 4 : Envoyez le reçu à l’aide de Send API v3.1
La partie la plus excitante est maintenant l’envoi de l’email de reçu dynamique. Voici un exemple complet qui comprend les variables du modèle, la pièce jointe au PDF et la configuration appropriée :
curl -s -X POST \
--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
https://api.mailjet.com/v3.1/send \
-H 'Content-Type: application/json' \
-d '{
"Messages":[
{
"From":{"Email":"billing@yourbrand.com","Name":"Facturation — Votre marque"},
"To":[{"Email":"customer@example.com","Name":"{{data:firstname:\"Client\"}}"}],
"TemplateID": TEMPLATE_ID,
"TemplateLanguage": true,
"Subject": "Votre reçu {{var:order_id}}",
"Variables": {
"order_id": "ORD-98765",
"order_date": "2025-08-27",
"currency": "USD",
"items": [
{"name":"Baskets","qty":1,"price":"99,00 €"},
{"name":"Chaussettes","qty":2,"price":"10,00 €"}
],
"money":{"subtotal":"119,00 €","tax":"9,52 €","discount":"0,00 €","total":"128,52 €"},
"has_shipping": true,
"shipping":{"name":"A. Smith","address1":"10 Market St","city":"Austin"},
"payment":{"brand":"Visa","last4":"4242"},
"order_url":"https://yourapp.com/orders/ORD-98765",
"support_email":"support@votremarque.com",
"year":"2025"
},
"Attachments":[
{
"ContentType":"application/pdf",
"Filename":"Facture-ORD-98765.pdf",
"Base64Content":"<base64-encoded-pdf>"
}
]
}
]
}'
Options d’envoi utiles
- Globals : évitez les répétitions dans les envois groupés (From, Subject, headers)
- SandboxMode : la valeur true permet de valider la charge utile sans l’envoyer
- CustomID : utilisez « order-ORD-98765 » pour corréler les événements
- URLTags : ajoutez « utm_source=receipt&utm_medium=email » pour le suivi
URLTags : ajoutez « utm_source=receipt&utm_medium=email » pour le suivi
Étape 5 : Vérifiez la livraison et suivez les événements
Le suivi de l’acheminement des emails est essentiel pour maintenir la confiance des clients et résoudre les problèmes.
Mise en place de webhooks
Enregistrez votre point de terminaison webhook pour recevoir des événements en temps réel :
- Envoyé, livré, ouvert, cliqué
- Rebond, plaintes pour spam, bloqué
- Désinscrit
Vérification de l’état des messages
- Informations sur le message : GET /v3/REST/message/{Message_ID} pour les métadonnées
- Chronologie des événements : GET /v3/REST/messagehistory/{Message_ID} pour les événements détaillés
- Statistiques : utilisez /v3/REST/statcounters pour obtenir des statistiques agrégées sur les livraisons
Étape 6 : Internationalisation et devise
Pour les entreprises internationales, une localisation adéquate est essentielle :
- Mise en forme des devises : mettez en forme les montants côté serveur en fonction du lieu du destinataire et transmettez des chaînes prêtes à être rendues dans les variables (par exemple, money.total = "129,90 €").
- Texte alternatif : utilisez {{data:firstname:"Client"}} pour les alternatives tenant compte de la langue
- Modèles multilingues : soit vous conservez un modèle avec des blocs conditionnels ({% if var:locale == "fr" %}…{% endif %}), soit vous créez des modèles distincts pour chaque lieu
Étape 7 : Délivrabilité et conformité
Veillez à ce que vos reçus parviennent à la boîte de réception et soient conformes à la réglementation :
Configuration technique
- Vérifier votre domaine et configurer les enregistrements SPF/DKIM
- Envoyer à partir de votre domaine vérifié pour une meilleure réputation
- Les modèles doivent être légers, avec des images compressées et un minimum de polices externes
- Toujours fournir une version en texte brut
Sécurité et vie privée
- Ne jamais indiquer le numéro complet d’une carte de paiement, mais seulement les 4 derniers chiffres et la marque
- Sécuriser les pièces jointes PDF et minimiser les informations confidentielles
- Respecter les préférences de désabonnement pour tout contenu promotionnel
Étape 8 : Conseils avancés pour la production
Les équipes qui déploient à grande échelle peuvent envisager ces optimisations :
Stratégies de pièces jointes
- Utiliser les pièces jointes pour les PDF que les utilisateurs téléchargent
- Utiliser InlinedAttachments pour les logos référencés via cid: en HTML
Organisation de la campagne
- Définir CustomCampaign: « transactional_receipts » pour un meilleur reporting
- Activer DeduplicateCampaign pour éviter les envois en double dans les lots
Traitement et observabilité des erreurs
- Enregistrer les erreurs de Send API avec des codes et des champs spécifiques pour le débogage
- Étiqueter chaque envoi avec un CustomID pour faciliter la corrélation
- Inclure EventPayload avec les métadonnées de la commande pour le rapprochement en aval
Dépannage des problèmes courants
Voici quelques questions à résoudre si vous rencontrez des problèmes avec ce qui précède.
Les variables du modèle ne sont pas rendues
- S’assurer que TemplateLanguage: true est défini dans votre appel à Send API
- Vérifier que les noms des variables de votre modèle correspondent à ceux de l’objet Variables
Erreurs d’authentification
- « Sender not authorized » : validez d’abord votre domaine/adresse From
- Vérifier que les informations d’identification de votre API sont correctes et que vous disposez des autorisations nécessaires
Contenu manquant
- « At least HTMLPart, TextPart or TemplateID must be provided » : assurez-vous que vous fournissez un TemplateID
Problèmes de suivi des événements
- Confirmer que le point de terminaison de votre webhook renvoie HTTP 200
- Vérifier si votre point de terminaison webhook est soumis à une limitation de débit
- Envisager l’utilisation d’événements groupés pour les scénarios à fort volume
Prochaines étapes
Vous disposez désormais d’un système de reçu électronique complet et prêt à la production ! Voici quelques moyens de l’améliorer encore :
- Mise en œuvre d’A/B testing pour différents modèles de reçus
- Ajouter une logique conditionnelle plus sophistiquée pour différents types de produits
- Mettre en place un suivi automatisé et d’alertes en cas de problèmes de livraison
- Explorer l’API de statistiques de Mailjet pour obtenir des statistiques de performances détaillées
Pour des ressources supplémentaires et des échantillons de code, consultez le référentiel d’échantillons de modèles Mailjet qui comprend un exemple fonctionnel complet que vous pouvez utiliser comme point de départ.
Résumé
Ce guide vous accompagne dans la création d’un modèle de reçu professionnel en utilisant MJML pour le responsive design et le templating language de Mailjet pour le contenu dynamique. Vous avez appris à traiter des données de commande complexes, à joindre des factures au format PDF, à assurer une livraison fiable et à contrôler les performances, autant d’éléments essentiels à la mise en place d’un système d’email pour l’e-commerce qui évolue avec votre entreprise.