DEV Community

Cover image for Easier Responsive Emails for Umbraco Forms with MJML
Søren Kottal
Søren Kottal

Posted on

Easier Responsive Emails for Umbraco Forms with MJML

HTML emails are notoriously difficult to style due to inconsistent rendering across email clients. Fortunately, MJML provides a modern solution that simplifies email creation while ensuring compatibility.

Basically, HTML emails are a Frankenstein’s monster of old web practices, because they have to work in the wild west of email clients. If they were too advanced, half of your audience wouldn't be able to read them properly.

Exhibit A: The default Umbraco Forms Email Template

Here’s an excerpt of the default email template in Umbraco Forms. While functional, it requires extensive inline styling, uses outdated table-based layouts, and lacks flexibility.

    <style type="text/css">

    /* CLIENT-SPECIFIC STYLES */
    body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
    table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
    img { -ms-interpolation-mode: bicubic; }

    /* RESET STYLES */
    img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; }
    table { border-collapse: collapse !important; }
    body { height: 100% !important; margin: 0 !important; padding: 0 !important; width: 100% !important; }

    /* iOS BLUE LINKS */
    a[x-apple-data-detectors] {
        color: inherit !important;
        text-decoration: none !important;
        font-size: inherit !important;
        font-family: inherit !important;
        font-weight: inherit !important;
        line-height: inherit !important;
    }

 /* MOBILE STYLES */
 @@media screen and (max-width:600px){
  h1 {
   font-size: 32px !important;
   line-height: 32px !important;
  }
 }

    /* ANDROID CENTER FIX */
    div[style*="margin: 16px 0;"] { margin: 0 !important; }
    </style>
</head>
<body style="background-color: #f4f4f4; margin: 0 !important; padding: 0 !important;">
    <table border="0" cellpadding="0" cellspacing="0" width="100%" style="margin-bottom: 40px;">
        <!-- LOGO -->
        <tr>
            <td bgcolor="#413659" align="center">
                <!--[if (gte mso 9)|(IE)]>
                    <table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
                    <tr>
                    <td align="center" valign="top" width="600">
                <![endif]-->
                <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;">
                    <tr>
                        <td align="center" valign="top" style="padding: 40px 10px 40px 10px;">
                            <a href="http://umbraco.com" target="_blank">
                                <img alt="Logo" src="@assetUrl/umbraco-logo.png" width="40" height="40" style="display: block; width: 40px; max-width: 40px; min-width: 40px; font-family: 'Lato', Helvetica, Arial, sans-serif; color: #ffffff; font-size: 18px;" border="0">
                            </a>
                        </td>
                    </tr>
                </table>
                <!--[if (gte mso 9)|(IE)]>
                    </td>
                    </tr>
                    </table>
                <![endif]-->
            </td>
        </tr>
Enter fullscreen mode Exit fullscreen mode

Introducing MJML: The simpler approach

Writing HTML email templates like this can be tedious and error-prone. This is where MJML comes in.

MJML (Mailjet Markup Language) is a powerful open-source framework designed to simplify the creation of responsive email templates. Instead of manually coding complex HTML tables and inline styles, MJML offers an intuitive, component-based syntax that automatically generates well-structured and mobile-friendly emails.

Instead of handwriting nested tables, and conditional Internet Explorer comments, you use easy to remember elements like <mj-section>, <mj-column> , <mj-text> and so forth. MJML then converts your markup to real robot-barf-like HTML tables, with all the needed weird quirks to make it work in different email clients.

I won’t go into detail about how to write MJML, you can see that in their documentation. In this article, I want to show you how you can utilize MJML for creating email templates to be used with Umbraco Forms.

First up, I’ve created an MJML implementation of the default example email template provided with Umbraco Forms. Converting it from real robot-barf-like HTML tables to clean MJML, brings it down from 221 lines of code to just 103. And with the added benefit of getting much cleaner markup, that you would be less afraid of touching. You can see the difference here.

But how would you get the MJML converted to HTML before sending the email?

Rendering MJML to HTML in .NET

Since MJML doesn’t have official .NET support, you need a library to convert MJML into standard HTML before sending the email. Fortunately, a community-driven fork of MJML is available on NuGet, implementing all MJML features and actively maintained.

Without having to create your own workflow for Umbraco Forms, to convert the MJML into HTML renderable by email clients, you can use Mjml.Net directly in the razor views used by the default Razor workflow provided with Umbraco Forms.

This would typically require you to save all your markup to a string variable, and run that through the MjmlRenderer, like this:

    var mjmlRenderer = new MjmlRenderer();

    string text = @"
        <mjml>
            <mj-head>
                <mj-title>Hello World Example</mj-title>
            </mj-head>
            <mj-body>
                <mj-section>
                    <mj-column>
                        <mj-text>
                            Hello World!
                        </mj-text>
                    </mj-column>
                </mj-section>
            </mj-body>
        </mjml>";

    var (html, errors) = mjmlRenderer.Render(text, options);
Enter fullscreen mode Exit fullscreen mode

This converts the MJML into fully compatible HTML, which you can then send as an email.

Using MJML in Razor Views

I don’t like putting everything into a variable like this. Especially when I need to loop over form fields, and concatenate values in.

Instead of storing MJML as a string in your code, a cleaner approach is to use Razor views and the layout feature to process MJML dynamically. You can create an MjmlLayout.cshtml file like this:

@using Mjml.Net
@{
    // get the body content as string
    var content = RenderBody();

    // render using mjml.net
    var mjmlRenderer = new MjmlRenderer();
    var (html, errors) = mjmlRenderer.Render(content);

    // print the html
    @Html.Raw(html)
}
Enter fullscreen mode Exit fullscreen mode

Then, in your email template, simply reference the layout:

@{
    Layout = "MjmlLayout.cshtml";
}
Enter fullscreen mode Exit fullscreen mode

This way, the email template content is processed through the MJML renderer dynamically, allowing you to use Razor’s built-in functionality while leveraging MJML’s cleaner syntax.

Conclusion

By integrating MJML with Umbraco Forms, you achieve cleaner, more maintainable email templates while ensuring broad compatibility across email clients. This approach allows developers to focus on design and content rather than battling email client inconsistencies, ultimately simplifying the email creation process.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs