doc/install.md
You can install MJML with NPM to use it with NodeJS or the Command Line Interface. If you're not sure what those are, head over to Usage for other ways to use MJML.
npm install mjml
To work on MJML, make changes and create pull requests, download and install yarn for easy development.
git clone https://github.com/mjmlio/mjml.git && cd mjml
yarn
yarn build
You can also run yarn build:watch to rebuild the package as you code.
Don't want to install anything? Use the free online editor!
<figure> </figure> <p class="cta-container"><a class="cta" href="https://mjml.io/try-it-live">Try it live</a></p>MJML comes with an ecosystem of tools and plugins, check out:
For more information, check the Tooling section.
For more tools, check the Community page.
Compiles the file and outputs the HTML generated in
output.html
mjml input.mjml -o output.html
You can pass optional arguments to the CLI and combine them.
| argument | description | default value |
|---|---|---|
mjml [input] -o [output] | Writes the output to [output] | |
mjml [input] -s | Writes the output to stdout | |
mjml [input] -s --noStdoutFileComment | Writes the output to stdout without an comment containing the source file in the first line | the outputs first line contains the file in the format <!-- FILE: {filename} --> |
mjml -w [input] | Watches the changes made to [input] (file or folder) | |
mjml [input] --config.allowIncludes | Enables mj-include processing (true or false) | false |
mjml [input] --config.allowMixedSyntax | Allow mixing block tokens (e.g. {%...%}) with CSS tokens (e.g. color: {{...}}) in the same document | false |
mjml [input] --config.beautify | Beautifies the output (true or false) | true |
mjml [input] --config.includePath | Adds allowlisted include root(s), as a string path or JSON array of paths | |
mjml [input] --config.juicePreserveTags | Preserve some tags when inlining css, see mjml-cli documentation for more info | |
mjml [input] --config.minify | Minifies the output (true or false) | false |
mjml [input] --config.minifyOptions | Options for HTML minifier. Use minifyCss to control CSS minification (legacy: minifyCSS is still accepted). See mjml-cli documentation for more info | |
mjml [input] --config.mjmlConfigPath [mjmlconfigPath] | Uses the .mjmlconfig file in the specified path or directory to include custom components | The .mjmlconfig file in the current working directory, if any |
mjml [input] --config.sanitizeStyles | Optional setting when using templating syntax to sanitize the input to PostCSS preventing (true or false) errors | false |
mjml [input] --config.templateSyntax | JSON array of { prefix, suffix } objects to declare templating delimiters (used by sanitization and restore) | |
mjml [input] --config.useMjmlConfigOptions | Allows to use the options attribute from .mjmlconfig file | false |
mjml [input] --config.validationLevel | Validation level: strict, soft or skip | soft |
CSS minification is controlled via minifyCss. For backward compatibility, the legacy minifyCSS key is still accepted and mapped internally:
mjml input.mjml -o output.html --config.minify true --config.minifyOptions '{"minifyCss": false}'
# legacy:
mjml input.mjml -o output.html --config.minify true --config.minifyOptions '{"minifyCSS": false}'
# lite preset
mjml input.mjml -o output.html --config.minify true --config.minifyOptions '{"minifyCss": "lite"}'
# legacy equivalent (maps to lite)
mjml input.mjml -o output.html --config.minify true --config.minifyOptions '{"minifyCSS": true}'
# default preset with single quotes for strings
mjml input.mjml -o output.html --config.minify true --config.minifyOptions '{"minifyCss": {"preset":["default", {"normalizeString":{"preferredQuote":"single"}}]}}'
import mjml2html from 'mjml'
/*
Compile an mjml string
*/
async function renderMjml() {
const htmlOutput = await mjml2html(
`
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>
Hello World!
</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
`,
options,
)
/*
Print the responsive HTML generated and MJML errors if any
*/
console.log(htmlOutput)
}
renderMjml()
You can pass optional options as an object to the mjml2html function:
| option | accepts | description | default value |
|---|---|---|---|
| allowMixedSyntax | boolean | Allow mixing block tokens and CSS tokens within the same document when sanitizing/minifying CSS | false |
| beautify | boolean | Option to beautify the HTML output | false |
| filePath | string | Path of the input file or a base directory; determines the default include sandbox (includes are allowed only under this directory when enabled) | '.' |
| ignoreIncludes | boolean | Option to ignore mj-include instances | true |
| includePath | string or array of strings | One or more explicit directories where includes are allowed, in addition to filePath. Paths outside these directories are denied. | |
| fonts | object | Default fonts imported in the HTML rendered by MJML | See in index.js |
| juicePreserveTags | object | Optional setting when inlining CSS, see mjml-cli documentation for more info | |
| keepComments | boolean | Option to keep comments in the HTML output | true |
| minify | boolean | Option to minify the HTML output | false |
| minifyOptions | object | Options for HTML minifier, see mjml-cli documentation for more info | {"collapseWhitespace": true, "minifyCss": "lite", "removeEmptyAttributes": true} |
minifyCss can be false, lite, default, or a cssnano preset object, for example minifyCss: { preset: ['default', { normalizeString: { preferredQuote: 'single' } }] } |
| mjmlConfigPath | string | The path or directory of the .mjmlconfig file | process.cwd() |
| preprocessors | array of functions | Preprocessors applied to the xml before parsing. Functions must be (xml: string) => string | [] |
| sanitizeStyles | boolean | Optional setting when using templating syntax to sanitize the input to PostCSS preventing errors | false |
| templateSyntax | array of objects | When sanitizeStyles is true, you can pass optional syntax e.g. templateSyntax: [{ prefix: '{{', suffix: '}}' }, { prefix: '{=', suffix: '=}' }] | [{"prefix":"{{","suffix":"}}"},{"prefix":"[[","suffix":"]]"}] |
| useMjmlConfigOptions | boolean | Allows to use the options attribute from .mjmlconfig file | false |
| validationLevel | string | Available values for the validator: strict soft skip | soft |
Includes are ignored by default for security (ignoreIncludes: true). Enable them explicitly and scope allowed folders with includePath.
CLI example:
$> mjml template.mjml \
--config.filePath /project/templates/newsletter \
--config.allowIncludes true \
--config.includePath '["../_common","../vendor"]'
import mjml2html from 'mjml'
async function compileOne(source) {
const { html, errors } = await mjml2html(source, {
ignoreIncludes: false,
filePath: '/project/templates/campaignA/email1.mjml',
includePath: '/project/templates/_common',
})
}
async function compileMany(source) {
const { html, errors } = await mjml2html(source, {
ignoreIncludes: false,
filePath: '/project/templates/campaignA/email1.mjml',
includePath: ['/project/templates/_common', '/project/templates/_footers'],
})
}
Security notes:
ignoreIncludes: true). Enable explicitly and scope allowed folders with includePath.%252F).//server/... or \\server\\...), Windows drive letters (C:\...), and null bytes (%00).realpath and require the target to stay inside filePath or any includePath roots.filePath to your templates root and write includes relative to that base (e.g., ./_common/header.mjml). Simple setup; templates must use base-relative paths.../_common/header.mjml) and declare includePath with sibling/shared folders. No template changes; supports multiple shared roots.filePath and includePath are allowed. Absolute paths outside these roots and .. escapes are denied.A free-to-use MJML API is available to make it easy to integrate MJML in your application. Head over here to learn more about the API.