Browser-compatible version of MJML framework for client-side responsive email generation
npx @tessl/cli install tessl/npm-mjml-browser@4.15.0MJML Browser is a client-side version of MJML (Mailjet Markup Language) that enables responsive email template generation directly in web browsers. It provides the full MJML compilation engine as a UMD bundle, making it possible to convert MJML markup to responsive HTML without server-side processing.
npm install mjml-browservar mjml2html = require('mjml-browser');UMD/Browser Global:
// Available as global 'mjml' when loaded via script tag
var result = mjml(mjmlString, options);ES6 (if using with bundler):
import mjml2html from 'mjml-browser';var mjml2html = require('mjml-browser');
// Simple usage
var mjmlMarkup = `
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>Hello World!</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
`;
var result = mjml2html(mjmlMarkup);
console.log(result.html); // Generated responsive HTML
console.log(result.errors); // Validation errors/warningsMJML Browser is built around several key architectural components that work together to transform MJML markup into responsive HTML:
The browser version maintains the same component architecture as the Node.js version but replaces filesystem operations with mocked implementations, enabling client-side email template generation while preserving full MJML functionality.
Core function that converts MJML markup into responsive HTML email templates.
/**
* Converts MJML markup to responsive HTML
* @param {string|object} mjml - MJML markup string or parsed MJML object
* @param {object} [options={}] - Configuration options
* @returns {object} Result object with html, json, and errors
*/
function mjml2html(mjml, options);
interface MjmlResult {
html: string; // Generated responsive HTML
json: object; // Parsed MJML object representation
errors: Array<ValidationError>; // Validation errors and warnings
}
interface ValidationError {
line: number;
message: string;
tagName: string;
formattedMessage: string;
}Comprehensive options for customizing MJML compilation behavior.
interface MjmlOptions {
/** Format HTML output (deprecated, use external tool) */
beautify?: boolean;
/** Custom font definitions with URLs */
fonts?: {
[fontName: string]: string;
};
/** Preserve HTML comments in output */
keepComments?: boolean;
/** Minify HTML output (deprecated, use external tool) */
minify?: boolean;
/** HTML minification options when minify is true */
minifyOptions?: object;
/** Ignore mj-include tags (always true in browser) */
ignoreIncludes?: boolean;
/** Options for CSS inlining with juice */
juiceOptions?: object;
/** Tags to preserve during CSS inlining */
juicePreserveTags?: {
[tagName: string]: any;
};
/** Custom HTML skeleton template function or string path */
skeleton?: Function | string;
/** Validation strictness: 'skip', 'soft', 'strict' */
validationLevel?: 'skip' | 'soft' | 'strict';
/** File path for error reporting */
filePath?: string;
/** Actual file path for includes (not functional in browser) */
actualPath?: string;
/** Suppress MJML v3 migration warnings */
noMigrateWarn?: boolean;
/** Custom preprocessor functions */
preprocessors?: Array<Function>;
/** Component and dependency presets */
presets?: Array<{
components: object;
dependencies: object;
}>;
/** Add printer-friendly styles */
printerSupport?: boolean;
}Access to MJML's component system for advanced usage.
/** Registry of available MJML components */
var components: object;
/**
* Initialize a component instance
* @param {object} config - Component configuration
* @returns {object|null} Component instance or null
*/
function initComponent(config);
/**
* Register a custom component
* @param {object} component - Component definition
*/
function registerComponent(component);
/**
* Assign components to component registry
* @param {object} target - Target component registry
* @param {object} source - Source components to assign
*/
function assignComponents(target, source);Helper functions for CSS and component manipulation.
/**
* Create responsive breakpoint CSS
* @param {string} breakpoint - Breakpoint value
* @returns {string} CSS media query
*/
function makeLowerBreakpoint(breakpoint);
/**
* Add suffix to CSS class names
* @param {string} classes - CSS classes string
* @param {string} suffix - Suffix to add
* @returns {string} Modified CSS classes
*/
function suffixCssClasses(classes, suffix);
/**
* Initialize MJML component types
* @param {object} type - Type definition
* @returns {object} Initialized type
*/
function initializeType(type);Base classes for creating custom MJML components.
/**
* Base class for MJML body components
*/
class BodyComponent {
constructor(initialDatas);
render();
}
/**
* Base class for MJML head components
*/
class HeadComponent {
constructor(initialDatas);
handler();
}Error class for validation failures in strict mode.
/**
* Error thrown when validation fails in strict mode
*/
class ValidationError extends Error {
constructor(message, errors);
/** Array of detailed validation errors */
errors: Array<object>;
}{
'Open Sans': 'https://fonts.googleapis.com/css?family=Open+Sans:300,400,500,700',
'Droid Sans': 'https://fonts.googleapis.com/css?family=Droid+Sans:300,400,500,700',
'Lato': 'https://fonts.googleapis.com/css?family=Lato:300,400,500,700',
'Roboto': 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700',
'Ubuntu': 'https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700'
}The browser version of MJML provides nearly identical functionality to the Node.js version but with specific limitations due to the browser security model and environment constraints:
fs module calls are replaced with browser-compatible mockstrue regardless of settingvar result = mjml2html(mjmlString, {
fonts: {
'Custom Font': 'https://fonts.example.com/custom-font.css'
}
});try {
var result = mjml2html(mjmlString, {
validationLevel: 'strict'
});
} catch (error) {
if (error instanceof ValidationError) {
console.log('Validation errors:', error.errors);
}
}var result = mjml2html(mjmlString, {
juiceOptions: {
preserveImportant: true,
removeStyleTags: false
}
});// Register a custom component
registerComponent({
name: 'mj-custom',
handler: function() {
return '<div>Custom content</div>';
}
});
// Use the custom component
var mjmlWithCustom = `
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-custom></mj-custom>
</mj-column>
</mj-section>
</mj-body>
</mjml>
`;