Using mjml in Sylius for email formating

Steph T
2 min readOct 20, 2022

--

Composing responsive email that fit in every client is time-consuming and painful. Fortunately, mailjet provide mjml a markup language that enable composing responsive email with a simplified semantic syntax.
mjml open-source engine could then translate MJML syntax into responsive email.

Let’s see how to integrate this with Symfony-based eCommerce framework Sylius to easily send nice transactional emails.

An old mailbox on a brick wall
Stefan Hoffmann via pixabay

1/ Install mjml in your stack

With yarn:
yarn add mjml

With npm:
npm install mjml --save

You could then use the CLI to generate HTML outpout file from MJML template:
mjml input.mjml -o output.html

2/ Install a MJML renderer

We need an way to render MJML to HTML, this could be done by writing a custom Renderer and configuring Sylius to use it.

But to be able to use both default Sylius emails and use MJML progressively or on few emails only, another solution could be used:
The default html.twig email templates are still called, but they include a mjml.twig template rendered in html.

To use this, we need a Twig MJML extension like qferr / mjml-twig

Install it with composer in your Symfony project:
composer require qferr/mjml-twig

And configure it into config/services.yaml:

services:
......
Qferrer\Mjml\Renderer\BinaryRenderer:
arguments: [‘%kernel.project_dir%/node_modules/.bin/mjml’]
Qferrer\Mjml\Twig\MjmlExtension:
arguments: [‘@Qferrer\Mjml\Renderer\BinaryRenderer’]
tags: [‘twig.extension’]

‘%kernel.project_dir%/node_modules/.bin/mjml’ is the path to your binary mjml engine.

3/ Create and configure a new template directory and namespace to store mjml files

Create a new directory to store mjml templates, for exemple into default Sylius template directory templates :
mkdir ./templates/mjml :

And register it as a twig directory inconfig/packages/twig.yaml :

twig:
.....
paths:
.....
"%kernel.project_dir%/templates/mjml/": AppMjml

4/ Override Sylius email templates

To keep things separated, we need to compose a templates/mjml/layout.mjml.twig and several other files (_header.mjml.twig, _footer.mjml.twig…)

The templates/mjml/layout.mjml.twig includes the mjml_to_html twig filter from qferr/mjml-twig:

and at least, the email templates !

Sylius as already few emails configured
https://sylius-older.readthedocs.io/en/latest/book/emails.html

For example, let’s change password reset email:

4.1/ Copy/paste passwordReset.html.twig

As usual with Sylius, copy the twig template from the CoreBundle to your project template directory to override it:
cp ./sylius/vendor/sylius/sylius/src/Sylius/Bundle/CoreBundle/Resources/views/Email/passwordReset.html.twig ./templates/bundles/SyliusShopBundle/Email/passwordReset.html.twig

Edit passwordReset.html.twig, to personalize the template to your needs. You could remplace all with:

4.2/ Create the mjml template

Create the file templates/mjml/passwordReset.mjml.twig using mjml syntax, for example:

5/ Test it !

For example, with MailDev
Don’t forget to check the email in the most clients possible.

--

--

Steph T

Senior Backend Developer, interests on code quality and devops #symfony #sylius