Générer des mails en un clin d’œil avec Vue et MJML

Une solution developer-friendly pour un résultat flexible et compatible

Nico Prat
Nico Prat
Jun 13, 2020 · 4 min read

La gestion des mails est rarement une partie de plaisir dans le développement d’une application, mais il est encore plus rare de pouvoir s’en passer. Entre la solution minimaliste du format texte uniquement, et les outils graphiques tout intégrés tels que Mailchimp, il n’est pas toujours facile de trouver un compromis.

Ces dernières années on a vu apparaître une nouvelle approche dans la construction de mail, à savoir des langages qui abstraient HTML et génèrent un code compatible avec un maximum de clients mails. C’est l’occasion parfaite pour intégrer cet outil à un framework comme Vue. On parlera ici de MJML, la solution de Mailjet, que vous pouvez tester ici : https://mjml.io/try-it-live. Comparons avec les solutions via interface graphique :

Avantages 👍

  • expérience développeur (code proche de HTML)
  • maintenance (gestion de source avec Git)
  • flexibilité (génération automatique complète selon les données)
  • partage de code (avec le frontend essentiellement)

Inconvénients 👎

  • inaccessible (ou presque) aux non-développeurs
  • demande l’apprentissage d’un nouveau langage
  • restreint les possibilités graphiques pour garantir la compatibilité

On pourrait tout à fait utiliser cet outil dans l’interface de Mailjet et se limiter à un usage ponctuel, mais on va voir ici comment mieux intégrer cet outil dans un projet Vue et l’automatiser côté serveur (avec Node). Voilà le plan :

  1. Créer un template générique
  2. Récupérer des données selon le contexte
  3. Générer le code MJML avec Vue
  4. Réutiliser vue-router et vue-i18n
  5. Compiler le code MJML en HTML
  6. Envoyer le mail

Avant de passer ces points en revue, voilà un aperçu de ce que donne ce système :

Il est aussi possible de voir le résultat dans l’éditeur MJML en ligne de Mailjet : https://mjml.io/try-it-live/H1udcVZ6I

1⃣ Créer un template Vue générique

On peut reprendre le code d’exemple de MJML et y ajouter des directives Vue. Je n’ai pas trouvé de limites particulières à l’usage. Les principales restrictions viendront donc principalement de MJML dans un souci de compatibilité. Exemple rapide avec v-if, v-for et v-bind :

2⃣ Contextualiser les données

Passons rapidement sur ce point qui n’est pas spécifique à Vue ou MJML. La première étape consiste à récupérer les données qui vont alimenter le template. Selon la complexité, à vous de voir comment vous organiser. De notre côté, on a une douzaine de types de mails différents, on a donc créé une configuration où chaque mail est identifié par un code. On a ensuite plusieurs niveaux de contexte :

  • commun à tous les mails : par exemple l’email du destinataire
  • commun à un type de mail : par exemple une illustration d’entête
  • spécifique à un mail précis : par exemple le texte principal
  • spécifique à un destinataire précis : par exemple sa langue d’affichage

Dans l’exemple, le contexte est simulé de manière statique dans plusieurs fichiers : config.js , users.js , router.js , et enfin la configuration des mails dans email.js

3⃣ Générer le template MJML

Une fois toutes les variables en main, on peut générer dynamiquement le template grâce à vue-server-renderer de manière très simple :

On est vraiment très proche du code frontend, qui aurait crû qu’il serait si simple de faire du SSR (Server Side Rendering) ?

Puisqu’on veut générer des balises MJML (liste des composants), on doit par contre ignorer les éléments HTML commençant par mjml- pour éviter des erreurs puisque Vue aurait cherché un composant du même nom ; heureusement il existe l’option ignoredElements pour ne pas prendre en compte un pattern spécifique.

4⃣ Utiliser vue-router et vue-i18n

Profitons-en pour partager la définition des routes et des traductions, puisque c’est l’un des avantages à utiliser Vue côté serveur. À nouveau, rien de bien différent du frontend, si ce n’est qu’il faut forcer vue-router à créer des liens absolus, ce qui oblige à passer par une méthode par exemple :

5⃣ De MJML à HTML

Le plus dur est fait ! La librairie officielle MJML pour Node est particulièrement simple d’utilisation :

Vous remarquerez qu’il est nécessaire de supprimer un attribut ajouté par vue-server-renderer, à savoir data-server-rendered pour éviter que le compiler MJML émette un warning.

6⃣ Envoyer le mail avec Mailjet

Dernière étape, envoyer ce mail ; Mailjet propose une librairie officielle pour Node :

Dans le code d’example, vous pouvez créer un fichier .env avec vos clés d’API Mailjet pour faire un test d’envoi :

MAILJET_PUBLIC=xxx
MAILJET_PRIVATE=xxx

Quelques bémols

On pourra reprocher à ce système qu’il devient difficile pour les non-développeurs (designers, équipe produit, marketing…) d’avoir un aperçu visuel du rendu dans un contexte particulier. Comment être sûr que le mail de bienvenue ressemble bien à ce qu’on imagine ? Que les traductions sont bien prises en compte ?

On peut envoyer des mails de test via Mailjet directement mais ce n’est pas le plus rapide et pratique ; de plus ces mails sont comptés dans les quota. Pour notre part on utilise actuellement la fonctionnalité de snapshots de Jest pour avoir un exemple “type” de chaque configuration de mail, mais ça reste le point faible de notre solution pour le moment.

nicooprat

Myself

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store