Migrating from MJML
Coming from MJML, once you switch your mental model to the Vue syntax you'll find a lot of familiar concepts in Maizzle, but with more flexibility and power under the hood.
Component map
| MJML | Maizzle |
|---|---|
<mjml> | Html |
<mj-head> | Head |
<mj-title> | useHead() |
<mj-preview> | Preheader |
<mj-body> | Body |
<mj-section> | Section |
<mj-group> | Row |
<mj-column> | Column |
<mj-text> | Text |
<mj-button> | Button |
<mj-image> | Img |
<mj-divider> | Hr |
<mj-spacer> | Spacer |
<mj-table> | Plain <table> with Tailwind classes |
<mj-raw> | Raw |
<mj-html-attributes> defaults | html.attributes.add |
<mj-style> | <style> block in <Head> |
<mj-include> | Custom Vue component |
Maizzle components
These have no MJML equivalent, here's what you've been missing out on:
| Component | Purpose |
|---|---|
| Layout | Opinionated skeleton with email-safe defaults |
| Container | Centered content wrapper |
| Heading | Headings with semantic markup |
| Link | Unstyled hyperlink |
| Tailwind | Enables Tailwind CSS for styling |
| Markdown | Render markdown content |
| CodeBlock / CodeInline | Syntax-highlighted code / Inline code formatting |
| Font | Use custom fonts |
| Outlook | Render content only for Outlook |
| NotOutlook | Render content everywhere except Outlook |
| OutlookBg | Outlook background images with VML |
| NoWidows | Prevent orphaned words |
| WithUrl | Add base URLs and tracking query params |
| Plaintext | Render content only in the plaintext output |
| NotPlaintext | Render content everywhere except in the plaintext output |
| QrCode | Generate inline QR codes using tables |
Side-by-side
<mjml>
<mj-head>
<mj-title>Welcome to Acme</mj-title>
<mj-preview>Let's get you set up.</mj-preview>
<mj-attributes>
<mj-all font-family="Helvetica, Arial, sans-serif" />
<mj-text color="#475569" font-size="16px" />
</mj-attributes>
</mj-head>
<mj-body background-color="#ffffff">
<mj-section>
<mj-column>
<mj-text font-size="24px" color="#0f172a">Hi {{ name }}</mj-text>
<mj-text>Thanks for signing up. Click below to verify your email.</mj-text>
<mj-button href="https://example.com/verify" background-color="#2563eb">
Verify email
</mj-button>
</mj-column>
</mj-section>
</mj-body>
</mjml>
Styling
MJML uses tag attributes (background-color, font-size, padding) on every element.
In Maizzle, you can use Tailwind utility classes or inline CSS.
Includes and partials
<mj-include path="./header.mjml" /> becomes a custom Vue component:
<template>
<Section class="py-4">
<Img src="/logo.png" alt="Acme" width="120" />
</Section>
</template>
Components are auto-imported, no manual import statements needed. See Components.
Compiling emails
Use the Maizzle CLI in place of the MJML one:
mjml file.mjml -o dist/file.html
Or programmatically with build():
build.ts
import { build } from '@maizzle/framework'
const { files } = await build({
content: ['emails/**/*.vue'],
output: { path: 'dist' },
})
Or, to render a single email template and get the compiled HTML string:
import mjml2html from 'mjml'
const { html } = mjml2html('<mjml>...</mjml>')