Use in Node.js

You can use Maizzle in your Node.js app, to compile a string to an HTML email.

Usage

First, require() the framework in your application:

const Maizzle = require('@maizzle/framework')

Then, call the render() method, passing it a string and an options object:

Maizzle
  .render(`html string`, options)
  .then(({html, config}) => console.log(html, config))

The render() method returns an object containing the compiled HTML and the environment config computed for this template.

Options

options is an object with the following structure:

{
  tailwind: {
    config: {},
    css: '',
    compiled: '',
  },
  maizzle: {},
  beforeRender() {},
  afterRender() {},
  afterTransformers() {},
}
tailwind

Pass in a custom Tailwind CSS configuration, or a pre-compiled CSS string.

OptionTypeDefaultDescription
configObject{}A Tailwind CSS config object.
cssString@tailwind components; @tailwind utilities;A string with CSS in PostCSS syntax. Gets compiled with Tailwind CSS. To use Tailwind, you should at least use @tailwind utilities
compiledString(empty string)A pre-compiled CSS string, to use as-is. This will skip Tailwind compilation, resulting in faster render speed.
maizzle

The Maizzle environment configuration object.

TypeDefaultDescription
Object{}A Maizzle config object.

Example

const Maizzle = require('@maizzle/framework')

const template = `---
title: Using Maizzle on the server
---

<!DOCTYPE html>
<html>
  <head>
    <if condition="page.css">
      <style>{{{ page.css }}}</style>
    </if>
  </head>
  <body>
    <table>
      <tr>
        <td class="button">
          <a href="https://maizzle.com">Confirm email address</a>
        </td>
      </tr>
    </table>
  </body>
</html>`

Maizzle.render(
  template,
  {
    tailwind: {
      config: require('./tailwind.config'),
      css: `
        @tailwind utilities;
        .button { @apply rounded text-center bg-blue-500 text-white; }
        .button:hover { @apply bg-blue-700; }
        .button a { @apply inline-block py-16 px-24 text-sm font-semibold no-underline text-white; }
      `,
    },
    maizzle: require('./config.js')
  }
).then(({html}) => console.log(html)).catch(error => console.log(error))

Templating

You can use templating tags when using Maizzle in Node.js.

Here's the template string defined above, refactored to extend a Layout:

const template = `---
title: Using Maizzle on the server
---

<extends src="src/layouts/main.html">
  <block name="template">
    <table>
      <tr>
        <td class="button">
          <a href="https://maizzle.com">Confirm email address</a>
        </td>
      </tr>
    </table>
  </block>
</extends>`

Gotchas

Since the config you can pass to the render() method is optional, there are a few gotchas that you need to be aware of.

Default Tailwind

If you don't specify a Tailwind config object, Maizzle will try to compile Tailwind using tailwind.config.js at your current path.

If the file is not found, Tailwind will be compiled with its default config.

The default config is not optimized for HTML email: it uses units like rem and CSS properties that are used for web design and which have little to no support in the majority of email clients.

Safe Class Names

The safeClassNames Transformer runs only when an environment name is specified, and as long as that name is not local.

If you don't specify it in the maizzle object, class names won't be rewritten with email client-safe characters. This could break rendering in some clients, such as Gmail.

To avoid this, always specify the environment name:

Maizzle.render('html string', {
  maizzle: {
    env: 'node',
  }
}).then(({html}) => console.log(html))

Transformers

Transformers, such as CSS inlining or minification, are opt-in: they transform content only when you enable them. Since you don't need to pass in a Maizzle config object, this means that most of them will not run.

The following Transformers always run:

  • Markdown (can be disabled)
  • Prevent Widows
  • Remove Attributes - removes empty style attributes by default
  • Transform Contents - processes CSS with PostCSS inside elements with a postcss attribute

CSS Output

Your string that you compile with render() must include {{{ page.css }}} in a <style> tag inside the <head>, otherwise no CSS will be output or inlined:

  <!DOCTYPE html>
  <html>
+    <head>
+      <if condition="page.css">
+        <style>{{{ page.css }}}</style>
+      </if>
+    </head>
    <body>
      ...
    </body>
  </html>