Blog

Introducing MJML Support in v7

If you’ve ever tried to build an HTML email from scratch, you know that it’s not easy. Email clients don’t support modern HTML and CSS niceties and have a lot of quirks to be mindful of. Conveniences like CSS Grid or even Flexbox are unsupported, leaving us to rely on table tags. Achieving a polished look across various devices and browsers can be quite a challenge.

To make crafting emails a lot more enjoyable, the folks at Mailjet created a solution called MJML, which stands for “Mailjet Markup Language.” It’s an easy-to-use abstraction layer over HTML.

What is MJML?

MJML, developed by Mailjet, is a powerful open-source framework designed to simplify the creation of responsive and visually appealing email templates. Its user-friendly markup language abstracts the complexities of HTML and CSS coding, enabling marketers and developers to effortlessly design emails that render beautifully across a wide range of devices and email clients.

Taking a look at MJML

MJML looks very much like HTML but with mj tags. Let’s take a look at some valid MJML.

<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text invalid-attribute>Hello World</mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

In the code above, you can see that there are many mj components that you can make use of. I won’t explain them all as they are described in the extensive documentation. In those docs, you’ll also find a complete example of an entire mail.

When converting the MJML to HTML, this is the result:

<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">

<head>
  <title></title>
  <!--[if !mso]><!-->
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <!--<![endif]-->
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style type="text/css">
    #outlook a {
      padding: 0;
    }

    body {
      margin: 0;
      padding: 0;
      -webkit-text-size-adjust: 100%;
      -ms-text-size-adjust: 100%;
    }

    table,
    td {
      border-collapse: collapse;
      mso-table-space: 0pt;
      mso-table-space: 0pt;
    }

    img {
      border: 0;
      height: auto;
      line-height: 100%;
      outline: none;
      text-decoration: none;
      -ms-interpolation-mode: bicubic;
    }

    p {
      display: block;
      margin: 13px 0;
    }
  </style>
  <!--[if mso]>
    <noscript>
    <xml>
    <o:OfficeDocumentSettings>
      <o:AllowPNG/>
      <o:PixelsPerInch>96</o:PixelsPerInch>
    </o:OfficeDocumentSettings>
    </xml>
    </noscript>
    <![endif]-->
  <!--[if lte mso 11]>
    <style type="text/css">
      .mj-outlook-group-fix { width:100% !important; }
    </style>
    <![endif]-->
  <!--[if !mso]><!-->
  <link href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700" rel="stylesheet" type="text/css">
  <style type="text/css">
    @import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700);
  </style>
  <!--<![endif]-->
  <style type="text/css">
    @media only screen and (min-width:480px) {
      .mj-column-per-100 {
        width: 100% !important;
        max-width: 100%;
      }
    }
  </style>
  <style media="screen and (min-width:480px)">
    .moz-text-html .mj-column-per-100 {
      width: 100% !important;
      max-width: 100%;
    }
  </style>
  <style type="text/css">
  </style>
  <style type="text/css">
  </style>
</head>

<body style="word-spacing:normal;">
  <div style="">
    <!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
    <div style="margin:0px auto;max-width:600px;">
      <table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
        <tbody>
          <tr>
            <td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;">
              <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
              <div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
                <table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
                  <tbody>
                    <tr>
                      <td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
                        <div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:13px;line-height:1;text-align:left;color:#000000;">Hello World</div>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <!--[if mso | IE]></td></tr></table><![endif]-->
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <!--[if mso | IE]></td></tr></table><![endif]-->
  </div>
</body>
</html>

That’s a lot of HTML you didn’t have to come up with yourself. As you can see above, some code is being added to ensure it renders well in older email clients.

Coming soon in Mailcoach v7

We are currently working on the next major version of Mailcoach: v7. In this new version, we will have support for using MJML in your templates and campaigns.
We even have code completion suggestions in the CodeMirror editor. Yes, that’s also a new thing in the v7 release, a new Editor.

In addition to MJML support, we have much more in store.

Suppression List

Hard bounces will now be automatically added to a suppression list, ensuring they won’t be included in any email lists moving forward. You also have the flexibility to manually add or reactivate suppressed email addresses.

Livewire v3

With Livewire 3, we’ve made significant improvements, and we’ve also switched to Filament data tables for faster results.

Complex segment conditions

Instead of being limited to creating segments based solely on tags, we’ve expanded your options to create complex segments based on a variety of conditions.

We have many more features and fixes in the works, with a planned release for v7 in November. Stay tuned!

Ready to get started?