MJML - la bibliothèque open source pour créer facilement des emails responsives
📌 Introduction
Lorsqu'il s'agit de créer des emails, la compatibilité multiplateforme est souvent un véritable casse-tête. En effet, il est difficile de garantir que les emails s'afficheront correctement sur tous les clients de messagerie et sur tous les appareils. C'est là que MJML intervient.
MJML est une bibliothèque open source pour répondre aux personnes qui cherchent à créer des emails efficaces tout en réduisant le temps de développement. La bibliothèque est équipée de nombreuses fonctionnalités utiles, telles que des composants préconstruits pour les boutons, les tableaux, les listes, etc. MJML propose également une mise en page flexible et facilement personnalisable pour répondre aux besoins spécifiques de chaque projet.
💡 Pour l'hébergement des photos de vos mails, je vous conseille ImgBB. Il s'agit d'une plateforme en ligne gratuite qui permet d'héberger et de partager des images en toute simplicité. En l'utilisant, les utilisateurs peuvent visualiser les images rapidement, sans avoir besoin d'intégrer les images en pièces jointes. On ne peut utiliser le SVG ou le base64 sur toutes les plateformes.
🎯 Pourquoi MJML ?
Je l'utilise au quotidien pour faire des campagnes de mail responsive ou même de petits sites internet sur un seul fichier HTML. MJML résout les problèmes de compatibilité que l'on rencontre habituellement en générant automatiquement le HTML compatible avec tous les clients de messagerie.
| Fonctionnalité | Description |
|---|---|
mj-section |
Conteneur principal de mise en page responsive |
mj-column |
Colonne flexible adaptée à tous les écrans |
mj-text |
Bloc de texte stylisé et compatible |
mj-button |
Bouton cliquable rendu correctement sur tous les clients |
mj-image |
Image responsive avec lien et alt text |
📄 Exemple — Structure de base d'un email MJML
Voici un exemple minimal d'un email MJML complet avec un header, un corps de texte et un bouton d'appel à l'action :
<mjml>
<mj-head>
<mj-title>Mon Email Responsive</mj-title>
<mj-attributes>
<mj-all font-family="Roboto, Arial, sans-serif" />
<mj-text font-size="15px" color="#444444" line-height="1.6" />
</mj-attributes>
</mj-head>
<mj-body background-color="#f4f4f4">
<!-- Header -->
<mj-section background-color="#2c3e50" padding="20px">
<mj-column>
<mj-text color="#ffffff" font-size="24px" font-weight="bold" align="center">
Mon Blog — Newsletter
</mj-text>
</mj-column>
</mj-section>
<!-- Corps -->
<mj-section background-color="#ffffff" padding="30px 40px">
<mj-column>
<mj-text font-size="18px" font-weight="bold" color="#2c3e50">
Bonjour 👋
</mj-text>
<mj-text>
Voici le contenu principal de votre email. MJML génère automatiquement
le HTML compatible avec Outlook, Gmail, Apple Mail et tous les autres clients.
</mj-text>
<mj-image src="https://i.ibb.co/votre-image.png" alt="Image descriptive" width="600px" />
<mj-button background-color="#2980b9" color="#ffffff" href="https://blog.delacourt.ovh">
Lire l'article complet
</mj-button>
</mj-column>
</mj-section>
<!-- Footer -->
<mj-section background-color="#ecf0f1" padding="16px">
<mj-column>
<mj-text align="center" font-size="12px" color="#999999">
© 2026 blog.delacourt.ovh — Vous recevez cet email car vous êtes abonné.
</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
⚙️ Utilisation avec PowerShell — Compiler un fichier MJML
MJML s'installe via Node.js / npm. Une fois installé, il est possible de l'appeler
directement depuis PowerShell pour compiler vos fichiers .mjml en HTML prêt à l'envoi :
# ── Prérequis : Node.js installé ─────────────────────────────────────────────
# Installer MJML globalement via npm
npm install -g mjml
# ── Compiler un fichier MJML en HTML ─────────────────────────────────────────
$inputFile = "C:\Emails\newsletter.mjml"
$outputFile = "C:\Emails\newsletter.html"
mjml $inputFile -o $outputFile
Write-Output "Compilation terminée : $outputFile"
# ── Vérifier que le fichier HTML a bien été généré ────────────────────────────
if (Test-Path $outputFile) {
Write-Output "✅ Fichier HTML généré avec succès."
$size = (Get-Item $outputFile).Length / 1KB
Write-Output " Taille : $([math]::Round($size, 2)) Ko"
} else {
Write-Warning "❌ La compilation a échoué. Vérifiez votre fichier MJML."
}
🔁 Compiler tous les fichiers MJML d'un dossier
# ── Compiler tous les fichiers .mjml d'un dossier ────────────────────────────
$sourceFolder = "C:\Emails\Sources"
$outputFolder = "C:\Emails\Output"
# Créer le dossier de sortie s'il n'existe pas
if (-not (Test-Path $outputFolder)) {
New-Item -ItemType Directory -Path $outputFolder | Out-Null
}
# Boucle sur tous les fichiers .mjml
Get-ChildItem -Path $sourceFolder -Filter "*.mjml" | ForEach-Object {
$inputFile = $_.FullName
$outputFile = Join-Path $outputFolder ($_.BaseName + ".html")
Write-Output "Compilation : $($_.Name)"
mjml $inputFile -o $outputFile
if (Test-Path $outputFile) {
Write-Output " ✅ OK → $outputFile"
} else {
Write-Warning " ❌ ERREUR → $($_.Name)"
}
}
Write-Output ""
Write-Output "Compilation terminée pour tous les fichiers."
📧 Partie 4 — Envoyer un email avec un body MJML et des données PowerShell
Une fois le fichier MJML compilé en HTML, il est possible d'injecter dynamiquement des données
PowerShell dans le template avant l'envoi. L'idée est simple : on utilise des
marqueurs de substitution dans le fichier MJML (ex : {{NOM}},
{{TABLEAU}}), puis on les remplace via PowerShell avant d'envoyer l'email.
🏗️ Étape 1 — Créer le template MJML avec des marqueurs
Dans votre fichier rapport.mjml, placez des marqueurs aux endroits où les données
seront injectées :
<mjml>
<mj-head>
<mj-title>Rapport automatique</mj-title>
<mj-attributes>
<mj-all font-family="Roboto, Arial, sans-serif" />
<mj-text font-size="15px" color="#444444" line-height="1.6" />
</mj-attributes>
</mj-head>
<mj-body background-color="#f4f4f4">
<!-- Header -->
<mj-section background-color="#2c3e50" padding="20px">
<mj-column>
<mj-text color="#ffffff" font-size="22px" font-weight="bold" align="center">
📊 Rapport — {{DATE_RAPPORT}}
</mj-text>
</mj-column>
</mj-section>
<!-- Introduction personnalisée -->
<mj-section background-color="#ffffff" padding="30px 40px">
<mj-column>
<mj-text font-size="18px" font-weight="bold" color="#2c3e50">
Bonjour {{PRENOM_DESTINATAIRE}},
</mj-text>
<mj-text>
{{TEXTE_INTRO}}
</mj-text>
</mj-column>
</mj-section>
<!-- Tableau de données -->
<mj-section background-color="#ffffff" padding="0 40px 30px 40px">
<mj-column>
<mj-text font-size="16px" font-weight="bold" color="#2c3e50">
📋 Détail des éléments :
</mj-text>
<mj-text>
{{TABLEAU_HTML}}
</mj-text>
</mj-column>
</mj-section>
<!-- Résumé chiffré -->
<mj-section background-color="#eaf4fb" padding="20px 40px">
<mj-column>
<mj-text align="center" font-size="14px" color="#2980b9">
Total traité : <strong>{{TOTAL_ELEMENTS}}</strong> éléments
|
Erreurs : <strong>{{TOTAL_ERREURS}}</strong>
</mj-text>
</mj-column>
</mj-section>
<!-- Bouton -->
<mj-section background-color="#ffffff" padding="20px 40px">
<mj-column>
<mj-button background-color="#2980b9" color="#ffffff" href="{{LIEN_RAPPORT}}">
Consulter le rapport complet
</mj-button>
</mj-column>
</mj-section>
<!-- Footer -->
<mj-section background-color="#ecf0f1" padding="16px">
<mj-column>
<mj-text align="center" font-size="12px" color="#999999">
Rapport généré automatiquement par PowerShell — {{DATE_RAPPORT}}
</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
⚙️ Étape 2 — Script PowerShell : compiler, injecter et envoyer
Le script suivant effectue les opérations dans l'ordre :
- Compile le fichier
.mjmlen HTML viamjml - Charge le HTML compilé
- Génère un tableau HTML à partir de données PowerShell
- Injecte toutes les données dans le template via
-replace - Envoie l'email via
Send-MailMessageouSMTP
#Requires -Version 5.1
# =============================================================================
# CONFIGURATION
# =============================================================================
$mjmlFile = "C:\Emails\rapport.mjml"
$htmlFile = "C:\Emails\rapport.html"
$smtpServer = "smtp.votreserveur.com"
$smtpPort = 587
$smtpFrom = "rapport@votredomaine.com"
$smtpTo = "destinataire@exemple.com"
$smtpUser = "rapport@votredomaine.com"
$smtpPass = ConvertTo-SecureString "VotreMotDePasse" -AsPlainText -Force
# =============================================================================
# ÉTAPE 1 — Compiler le fichier MJML en HTML
# =============================================================================
Write-Output "Compilation MJML en cours..."
mjml $mjmlFile -o $htmlFile
if (-not (Test-Path $htmlFile)) {
Write-Error "La compilation MJML a échoué. Vérifiez le fichier source."
exit 1
}
Write-Output "✅ Compilation réussie : $htmlFile"
# =============================================================================
# ÉTAPE 2 — Charger le HTML compilé
# =============================================================================
$htmlBody = Get-Content -Path $htmlFile -Raw -Encoding UTF8
# =============================================================================
# ÉTAPE 3 — Préparer les données dynamiques
# =============================================================================
# ── Données textuelles ────────────────────────────────────────────────────────
$dateRapport = Get-Date -Format "dd/MM/yyyy à HH:mm"
$prenom = "Jean"
$texteIntro = "Veuillez trouver ci-dessous le rapport automatique généré ce jour. " +
"Ce rapport récapitule l'ensemble des opérations traitées par le système."
$lienRapport = "https://blog.delacourt.ovh"
# ── Données tabulaires (exemple : liste de machines/statuts) ──────────────────
$donnees = @(
[PSCustomObject]@{ Machine = "SRV-DC01"; Statut = "✅ OK"; Derniere_Sync = "06/03/2026 08:00" },
[PSCustomObject]@{ Machine = "SRV-FILE02"; Statut = "✅ OK"; Derniere_Sync = "06/03/2026 08:05" },
[PSCustomObject]@{ Machine = "SRV-PRINT03"; Statut = "⚠️ Warning"; Derniere_Sync = "05/03/2026 22:00" },
[PSCustomObject]@{ Machine = "SRV-APP04"; Statut = "❌ Erreur"; Derniere_Sync = "04/03/2026 14:30" },
[PSCustomObject]@{ Machine = "SRV-DB05"; Statut = "✅ OK"; Derniere_Sync = "06/03/2026 07:55" }
)
$totalElements = $donnees.Count
$totalErreurs = ($donnees | Where-Object { $_.Statut -like "*Erreur*" }).Count
# =============================================================================
# ÉTAPE 4 — Générer le tableau HTML depuis les données PowerShell
# =============================================================================
function New-HtmlTable {
param (
[Parameter(Mandatory)]
[object[]]$Data
)
$style = @"
"@
# En-têtes à partir des propriétés du premier objet
$headers = $Data[0].PSObject.Properties.Name
$headerRow = ($headers | ForEach-Object {
"$($_ -replace '_', ' ') "
}) -join ""
# Lignes de données
$rows = $Data | ForEach-Object {
$row = $_
$cells = ($headers | ForEach-Object {
"$($row.$_) "
}) -join ""
"$cells "
}
return "$style$headerRow $($rows -join '')
"
}
$tableauHtml = New-HtmlTable -Data $donnees
# =============================================================================
# ÉTAPE 5 — Injecter les données dans le template HTML
# =============================================================================
$htmlBody = $htmlBody `
-replace '\{\{DATE_RAPPORT\}\}', $dateRapport `
-replace '\{\{PRENOM_DESTINATAIRE\}\}', $prenom `
-replace '\{\{TEXTE_INTRO\}\}', $texteIntro `
-replace '\{\{TABLEAU_HTML\}\}', $tableauHtml `
-replace '\{\{TOTAL_ELEMENTS\}\}', $totalElements `
-replace '\{\{TOTAL_ERREURS\}\}', $totalErreurs `
-replace '\{\{LIEN_RAPPORT\}\}', $lienRapport
Write-Output "✅ Injection des données terminée."
# =============================================================================
# ÉTAPE 6 — Envoyer l'email via SMTP
# =============================================================================
$credential = New-Object System.Management.Automation.PSCredential($smtpUser, $smtpPass)
$mailParams = @{
SmtpServer = $smtpServer
Port = $smtpPort
UseSsl = $true
Credential = $credential
From = $smtpFrom
To = $smtpTo
Subject = "Rapport automatique — $dateRapport"
Body = $htmlBody
BodyAsHtml = $true
Encoding = [System.Text.Encoding]::UTF8
}
try {
Send-MailMessage @mailParams
Write-Output "✅ Email envoyé avec succès à $smtpTo"
} catch {
Write-Error "❌ Erreur lors de l'envoi : $_"
}
🔄 Principe de fonctionnement
| Marqueur dans le MJML | Valeur injectée par PowerShell | Type |
|---|---|---|
{{DATE_RAPPORT}} |
Date/heure d'exécution du script | Texte |
{{PRENOM_DESTINATAIRE}} |
Prénom issu d'Active Directory ou d'un CSV | Texte |
{{TEXTE_INTRO}} |
Paragraphe généré dynamiquement | Texte |
{{TABLEAU_HTML}} |
Tableau HTML généré depuis un PSCustomObject[] |
HTML |
{{TOTAL_ELEMENTS}} |
Comptage automatique des lignes | Nombre |
{{TOTAL_ERREURS}} |
Filtrage des lignes en erreur | Nombre |
{{LIEN_RAPPORT}} |
URL vers le rapport complet ou SharePoint | URL |
Get-Credential en interactif, ou stockez le mot de passe chiffré via
Export-Clixml / Import-Clixml pour les exécutions automatisées.
🔗 Liens utiles
- 📖 Documentation officielle MJML — Guide complet de tous les composants disponibles
- 🧪 MJML Try it live — Éditeur en ligne pour tester votre code MJML directement dans le navigateur
- 🎨 Templates MJML — Bibliothèque de templates responsives prêts à l'emploi
- 🖼️ ImgBB — Hébergement d'images gratuit pour vos emails
✅ Conclusion
MJML est un outil incontournable pour quiconque souhaite créer des emails responsives sans se perdre dans les subtilités de compatibilité entre clients de messagerie. Associé à PowerShell pour l'automatisation de la compilation, il devient un véritable atout dans un pipeline de communication.
Que ce soit pour des campagnes marketing, des notifications automatisées ou même de petits sites HTML monofichier, MJML simplifie considérablement le travail tout en garantissant un rendu professionnel sur tous les appareils.
💬 Vous utilisez MJML dans vos projets ? Partagez vos retours d'expérience en commentaires !

Commentaires
Enregistrer un commentaire