### Install Dependencies
Source: https://github.com/grapesjs/mjml/blob/master/README.md
Install project dependencies using npm. This command should be run after cloning the repository.
```sh
$ npm i
```
--------------------------------
### Start Development Server
Source: https://github.com/grapesjs/mjml/blob/master/README.md
Start the development server to run the GrapesJS MJML project. This command is used for local development and testing.
```sh
$ npm start
```
--------------------------------
### Initialize GrapesJS with MJML Plugin (HTML)
Source: https://github.com/grapesjs/mjml/blob/master/README.md
Basic setup for integrating the GrapesJS MJML plugin using HTML script tags. Ensure GrapesJS and the MJML plugin are included before this script.
```html
My Company
```
--------------------------------
### Clone GrapesJS MJML Repository
Source: https://github.com/grapesjs/mjml/blob/master/README.md
Clone the GrapesJS MJML repository to start development. This command downloads the project files.
```sh
$ git clone https://github.com/GrapesJS/mjml.git
$ cd mjml
```
--------------------------------
### Configure GrapesJS MJML Plugin with i18n
Source: https://github.com/grapesjs/mjml/blob/master/README.md
Example of initializing GrapesJS with the MJML plugin, including custom internationalization (i18n) settings for both GrapesJS core and the MJML plugin. Ensure locale files are correctly imported.
```javascript
import 'grapesjs/dist/css/grapes.min.css'
import grapesJS from 'grapesjs'
import nl from 'grapesjs/locale/nl'
import grapesJSMJML from 'grapesjs-mjml'
import mjmlNL from 'grapesjs-mjml/locale/nl'
grapesJS.init({
fromElement: true,
container: '#gjs',
i18n: {
// locale: 'en', // default locale
// detectLocale: true, // by default, the editor will detect the language
// localeFallback: 'en', // default fallback
messages: { nl: nl },
},
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
// Optional options
i18n: { nl: mjmlNL }
}
},
});
```
--------------------------------
### Get MJML String Command
Source: https://context7.com/grapesjs/mjml/llms.txt
Runs the 'mjml-code' command to retrieve the current editor canvas as a complete MJML string. Optionally includes `preMjml` and `postMjml` wrappers if configured.
```javascript
// Run the command to get the raw MJML source
const mjmlString = editor.Commands.run('mjml-code');
console.log(mjmlString);
// => '...'
// With preMjml / postMjml wrappers configured:
// editor was initialised with preMjml: '\n' and postMjml: '\n'
const wrapped = editor.Commands.run('mjml-code');
// => '\n...\n'
```
--------------------------------
### Opt out of Style Manager Reset
Source: https://context7.com/grapesjs/mjml/llms.txt
When `resetStyleManager` is true (default), the plugin installs three MJML-specific style sectors. Opt out to keep your own Style Manager.
```javascript
// The three sectors registered automatically:
// 1. "Dimension" — width, height, max-width, min-height, margin, padding, vertical-align, icon-size
// 2. "Typography" — font-family, font-size, font-weight, letter-spacing, color, line-height,
// text-align, align, text-decoration, font-style
// 3. "Decorations" — background-color, container-background-color, background-url,
// background-repeat, background-size, border-radius, border
// Opt out to keep your own Style Manager:
grapesJS.init({
plugins: [grapesJSMJML],
pluginsOpts: { [grapesJSMJML]: { resetStyleManager: false } },
});
// Accessing the Style Manager after init:
editor.onReady(() => {
const sectors = editor.StyleManager.getSectors();
sectors.each(sector => console.log(sector.get('name'))); // Dimension, Typography, Decorations
});
```
--------------------------------
### Custom MJML Parser Configuration
Source: https://context7.com/grapesjs/mjml/llms.txt
Replace the default mjml-browser with a custom build to include extended or proprietary MJML components. This setup also demonstrates registering corresponding GrapesJS component types using 'customComponents'.
```typescript
import grapesJS from 'grapesjs';
import grapesJSMJML from 'grapesjs-mjml';
import customMjmlBrowser from './my-custom-mjml-browser'; // extended mjml-browser build
const editor = grapesJS.init({
container: '#gjs',
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
mjmlParser: customMjmlBrowser,
// Pair with customComponents to register the matching GrapesJS component types:
customComponents: [
(editor, compOpts) => {
editor.Components.addType('mj-countdown', {
isComponent: (el) => el.tagName?.toLowerCase() === 'mj-countdown',
model: {
...compOpts.coreMjmlModel,
defaults: {
name: 'Countdown',
draggable: compOpts.componentsToQuery('mj-column'),
stylable: ['color', 'font-size'],
},
},
view: { ...compOpts.coreMjmlView },
});
},
],
},
},
});
```
--------------------------------
### Release Patch Version
Source: https://github.com/grapesjs/mjml/blob/master/README.md
Run this command to create a patch release, bumping the version in package.json and creating a git tag. This is the first step in the releasing process.
```sh
npm run v:patch
```
--------------------------------
### Initialize GrapesJS with MJML Plugin
Source: https://github.com/grapesjs/mjml/blob/master/index.html
This code initializes the GrapesJS editor and enables the MJML plugin. Ensure the plugin is available in the window scope before initialization.
```javascript
window.onload = () => {
window.editor = grapesjs.init({
height: '100%',
noticeOnUnload: false,
storageManager: false,
fromElement: true,
container: '#gjs',
plugins: ['grapesjs-mjml'],
pluginsOpts: {
'grapesjs-mjml': {}
}
});
}
```
--------------------------------
### Open Import Modal Command
Source: https://context7.com/grapesjs/mjml/llms.txt
Triggers the MJML import modal, which can be pre-filled with `importPlaceholder`. The user can then paste MJML to replace the current canvas components.
```javascript
// Trigger import programmatically (same as clicking the Import button in the toolbar)
editor.Commands.run('mjml-import');
// Pre-fill the modal with a starter template via plugin option:
grapesJS.init({
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
importPlaceholder: `Paste your MJML here`,
},
},
});
```
--------------------------------
### Initialize GrapesJS with Custom MJML Parser
Source: https://github.com/grapesjs/mjml/blob/master/README.md
Use this snippet to initialize GrapesJS with the MJML plugin, overriding the default MJML parser with a custom one and including custom MJML components. Ensure necessary imports are present.
```typescript
import 'grapesjs/dist/css/grapes.min.css'
import grapesJS from 'grapesjs'
import grapesJSMJML from 'grapesjs-mjml'
import customMjmlParser from 'custom-mjml-parser';
import customImage from 'custom/components/path'
grapesJS.init({
fromElement: true,
container: '#gjs',
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
mjmlParser: customMjmlParser,
customComponents: [
customImage,
]
}
},
});
```
--------------------------------
### mjml-import
Source: https://context7.com/grapesjs/mjml/llms.txt
Opens the MJML import modal, which is pre-filled with the `importPlaceholder` content. Users can then paste or type their MJML code, and upon clicking 'Import', the editor's canvas components will be replaced with the imported content.
```APIDOC
## Command: `mjml-import` — Open Import Modal
Opens the MJML import modal, pre-filled with `importPlaceholder`. The user pastes or types MJML, then clicks "Import" — the canvas components are replaced.
```js
// Trigger import programmatically (same as clicking the Import button in the toolbar)
editor.Commands.run('mjml-import');
// Pre-fill the modal with a starter template via plugin option:
grapesJS.init({
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
importPlaceholder: `Paste your MJML here`,
},
},
});
```
```
--------------------------------
### Switch Device Previews in GrapesJS
Source: https://context7.com/grapesjs/mjml/llms.txt
Use built-in commands to switch the editor viewport to Desktop, Tablet, or Mobile portrait preview. To retain the default device selector, set 'resetDevices' to false during initialization.
```javascript
editor.Commands.run('set-device-desktop'); // 600px+ desktop view
editor.Commands.run('set-device-tablet'); // tablet view
editor.Commands.run('set-device-mobile'); // mobile portrait view
// Disable the device reset to keep GrapesJS default device selector:
grapesJS.init({
plugins: [grapesJSMJML],
pluginsOpts: { [grapesJSMJML]: { resetDevices: false } },
});
```
--------------------------------
### Configure i18n / Localisation
Source: https://context7.com/grapesjs/mjml/llms.txt
Add translated UI strings by providing locale messages. The plugin ships with English built-in; other locales must be provided.
```javascript
import grapesJS from 'grapesjs';
import nl from 'grapesjs/locale/nl';
import grapesJSMJML from 'grapesjs-mjml';
import mjmlNL from 'grapesjs-mjml/locale/nl'; // ships with: ca de es fr he nl pl pt
grapesJS.init({
container: '#gjs',
i18n: {
locale: 'nl',
messages: { nl },
},
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
i18n: { nl: mjmlNL },
},
},
});
// Available locale keys inside 'grapesjs-mjml':
// panels.buttons.{ undo, redo, desktop, tablet, mobile, import }
// panels.import.{ title, button, label }
// panels.export.title
// components.names.{ body, button, column, oneColumn, twoColumn, threeColumn,
// divider, group, hero, image, navBar, navLink, section,
// socialGroup, socialElement, spacer, text, wrapper, raw }
```
--------------------------------
### Initialize GrapesJS with MJML Plugin (ESM)
Source: https://github.com/grapesjs/mjml/blob/master/README.md
Initialize GrapesJS with the MJML plugin using ESM imports. This method is suitable for modern JavaScript projects using module bundlers.
```javascript
import 'grapesjs/dist/css/grapes.min.css'
import grapesJS from 'grapesjs'
import grapesJSMJML from 'grapesjs-mjml'
grapesJS.init({
fromElement: true,
container: '#gjs',
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {/* ...options */}
},
});
```
--------------------------------
### Compile MJML to HTML Command
Source: https://context7.com/grapesjs/mjml/llms.txt
Compiles MJML from the current canvas or a provided string into HTML using `mjml-browser`. Returns an object with `html` and `errors` properties.
```javascript
// Compile the current canvas to HTML
const result = editor.Commands.run('mjml-code-to-html');
console.log(result.html); // full responsive HTML email string
console.log(result.errors); // array of MJMLError objects (empty when valid)
// Compile an arbitrary MJML string
const customMjml = `
Hello World
Click me
`;
const { html, errors } = editor.Commands.run('mjml-code-to-html', { mjml: customMjml });
if (errors.length) {
errors.forEach(e => console.warn(e.formattedMessage));
} else {
document.getElementById('preview').srcdoc = html;
}
```
--------------------------------
### Export Template Commands
Source: https://context7.com/grapesjs/mjml/llms.txt
Opens an export modal with a side-by-side view of MJML and compiled HTML. Overwrites the default GrapesJS export command if `overwriteExport` is true. Listen for compilation errors via the 'log' event.
```javascript
// Open the export dialog (dual MJML + HTML pane)
editor.Commands.run('export-template');
// If overwriteExport was set to false, use the explicit command ID:
editor.Commands.run('mjml-export');
// Listen for errors emitted during export compilation:
editor.on('log', (msg, opts) => {
if (opts.ns === 'mjml-code-to-html' && opts.level === 'warning') {
console.warn('MJML compile warning:', msg);
}
});
```
--------------------------------
### Configure Available Blocks
Source: https://context7.com/grapesjs/mjml/llms.txt
Restrict the availability of drag-and-drop blocks by passing a subset via the `blocks` option. Customise individual block properties using the `block` option.
```javascript
// All available block IDs:
const ALL_BLOCKS = [
'mj-1-column', // single-column section
'mj-2-columns', // two-column section
'mj-3-columns', // three-column section
'mj-text', // mj-text content block
'mj-button', // mj-button CTA block
'mj-image', // mj-image block
'mj-divider', // mj-divider horizontal rule
'mj-social-group', // mj-social with facebook/google/twitter elements
'mj-social-element',// single mj-social-element
'mj-spacer', // mj-spacer vertical space
'mj-navbar', // mj-navbar with four link items
'mj-navbar-link', // single mj-navbar-link
'mj-hero', // mj-hero full-width banner with bg image
'mj-wrapper', // mj-wrapper with bordered inner sections
'mj-raw', // mj-raw block for arbitrary HTML
];
// Register only layout blocks:
grapesJS.init({
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
blocks: ['mj-1-column', 'mj-2-columns', 'mj-3-columns', 'mj-wrapper', 'mj-hero'],
// Customise individual block properties:
block: (blockId) => {
if (blockId === 'mj-image') return { category: 'Media' };
if (blockId === 'mj-button') return { label: 'CTA Button' };
return {};
},
},
},
});
```
--------------------------------
### Enable XML Parser Mode
Source: https://context7.com/grapesjs/mjml/llms.txt
Enable the XML parser to allow importing self-closing MJML void elements like `` and ``. This experimental feature ensures MJML round-trips correctly.
```javascript
grapesJS.init({
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
useXmlParser: true,
},
},
});
// With XML parser, this MJML round-trips correctly:
editor.setComponents(`
Hello
`);
```
--------------------------------
### Using mjmlConvert Utility
Source: https://context7.com/grapesjs/mjml/llms.txt
The internal mjmlConvert utility safely wraps mjml-browser or a custom parser. It's useful when providing a custom mjmlParser and injects specified fonts into the compiled HTML.
```typescript
import mjmlBrowser from 'mjml-browser';
import { mjmlConvert } from 'grapesjs-mjml/src/components/utils'; // internal path
const fonts = {
Barlow: 'https://fonts.googleapis.com/css?family=Barlow',
};
const result = mjmlConvert(
mjmlBrowser,
`Hello`,
fonts,
// optional extra MJMLParsingOptions:
{ beautify: true },
);
console.log(result.html); // compiled HTML with Barlow font injected
console.log(result.errors); // []
```
--------------------------------
### export-template / mjml-export
Source: https://context7.com/grapesjs/mjml/llms.txt
Opens an export modal featuring a side-by-side code viewer that displays the current MJML code and its compiled HTML output simultaneously. This command replaces the default GrapesJS export command if `overwriteExport` is set to `true`.
```APIDOC
## Command: `export-template` / `mjml-export` — Open Export Modal
Opens a side-by-side code viewer showing the current MJML and its compiled HTML output simultaneously. Replaces the default GrapesJS export command when `overwriteExport: true`.
```js
// Open the export dialog (dual MJML + HTML pane)
editor.Commands.run('export-template');
// If overwriteExport was set to false, use the explicit command ID:
editor.Commands.run('mjml-export');
// Listen for errors emitted during export compilation:
editor.on('log', (msg, opts) => {
if (opts.ns === 'mjml-code-to-html' && opts.level === 'warning') {
console.warn('MJML compile warning:', msg);
}
});
```
```
--------------------------------
### Import MJML Template Programmatically
Source: https://context7.com/grapesjs/mjml/llms.txt
Load an MJML template string directly into the GrapesJS canvas without using the modal UI. This method clears existing content before setting the new components.
```javascript
const mjml = `
.slogan { background: #000; }A first line of textPromotionFacebookTwitter`;
// Clear existing content and load new template:
editor.Components.getWrapper()?.set('content', '');
editor.setComponents(mjml.trim());
```
--------------------------------
### Register grapesjs-mjml Plugin
Source: https://context7.com/grapesjs/mjml/llms.txt
Register the grapesjs-mjml plugin with GrapesJS, configuring various options for blocks, rendering, import/export, and styling.
```javascript
import 'grapesjs/dist/css/grapes.min.css';
import grapesJS from 'grapesjs';
import grapesJSMJML from 'grapesjs-mjml';
const editor = grapesJS.init({
container: '#gjs',
fromElement: false, // set true to parse existing HTML in the container
plugins: [grapesJSMJML],
pluginsOpts: {
[grapesJSMJML]: {
// ---- Block control ----
blocks: [
'mj-1-column', 'mj-2-columns', 'mj-3-columns',
'mj-text', 'mj-button', 'mj-image', 'mj-divider',
'mj-social-group', 'mj-social-element', 'mj-spacer',
'mj-navbar', 'mj-navbar-link', 'mj-hero', 'mj-wrapper', 'mj-raw',
],
block: (blockId) => blockId === 'mj-hero' ? { attributes: { title: 'Hero block' } } : {},
// ---- Rendering ----
columnsPadding: '10px 0', // padding added to column wrapper for easier selection
imagePlaceholderSrc: 'https://via.placeholder.com/350x250/78c5d6/fff',
// ---- Export/Import ----
overwriteExport: true, // replace GrapesJS default export command
preMjml: '', // prepend string to exported MJML
postMjml: '', // append string to exported MJML
importPlaceholder: '', // pre-fill import modal with sample MJML
// ---- Parser ----
codeViewerTheme: 'hopscotch', // CodeMirror theme for the MJML/HTML viewer
useXmlParser: false, // experimental: allows void tags like
// ---- Style / Layout ----
resetBlocks: true, // clear all pre-existing GrapesJS blocks
resetStyleManager: true, // replace Style Manager with MJML-specific sectors
resetDevices: true, // replace device buttons with Desktop/Tablet/Mobile
hideSelector: true, // hide default Selector Manager (classes unused in MJML)
useCustomTheme: true, // inject plugin colour theme into
// ---- Fonts ----
fonts: {
Barlow: 'https://fonts.googleapis.com/css?family=Barlow',
'Open Sans': 'https://fonts.googleapis.com/css?family=Open+Sans',
},
// ---- i18n ----
i18n: { nl: { 'grapesjs-mjml': { panels: { buttons: { import: 'Importeer MJML' } } } } },
},
},
});
```
--------------------------------
### mjml-code-to-html
Source: https://context7.com/grapesjs/mjml/llms.txt
Compiles either the current canvas MJML or a provided MJML string into production-ready HTML using `mjml-browser`. It returns an `MJMLParseResults` object containing the compiled HTML and any errors encountered during compilation.
```APIDOC
## Command: `mjml-code-to-html` — Compile MJML → HTML
Compiles either the current canvas MJML or a provided MJML string into production-ready HTML using `mjml-browser`. Returns an `MJMLParseResults` object `{ html, errors }`.
```js
// Compile the current canvas to HTML
const result = editor.Commands.run('mjml-code-to-html');
console.log(result.html); // full responsive HTML email string
console.log(result.errors); // array of MJMLError objects (empty when valid)
// Compile an arbitrary MJML string
const customMjml = `
Hello World
Click me
`;
const { html, errors } = editor.Commands.run('mjml-code-to-html', { mjml: customMjml });
if (errors.length) {
errors.forEach(e => console.warn(e.formattedMessage));
} else {
document.getElementById('preview').srcdoc = html;
}
```
```
--------------------------------
### PluginOptions Type Definition
Source: https://context7.com/grapesjs/mjml/llms.txt
TypeScript interface for all accepted plugin options. Customize block registration, component overrides, code viewer themes, and MJML parsing behavior.
```typescript
import type { Editor } from 'grapesjs';
import type { MJMLParsingOptions } from 'mjml-core';
import type { MjmlParser } from 'grapesjs-mjml';
// MjmlParser matches the mjml-browser / mjml-core call signature:
// (input: string | MJMLJsonObject, options?: MJMLParsingOptions) => MJMLParseResults
export type PluginOptions = {
blocks?: string[]; // subset of block IDs to register
block?: (blockId: string) => {}; // per-block overrides
codeViewerTheme?: string; // default: 'hopscotch'
customComponents?: ((editor: Editor, componentOptions: ComponentPluginOptions) => void)[];
importPlaceholder?: string;
imagePlaceholderSrc?: string;
mjmlParser?: MjmlParser; // swap in a custom mjml-browser build
overwriteExport?: boolean; // default: true
preMjml?: string;
postMjml?: string;
resetBlocks?: boolean; // default: true
resetStyleManager?: boolean; // default: true
resetDevices?: boolean; // default: true
hideSelector?: boolean; // default: true
useXmlParser?: boolean; // default: false (experimental)
columnsPadding?: string; // default: '10px 0'
i18n?: Record;
fonts?: Record; // font-name → Google Fonts URL
useCustomTheme?: boolean; // default: true
};
```
--------------------------------
### Register Custom GrapesJS MJML Components
Source: https://context7.com/grapesjs/mjml/llms.txt
Extend the component palette by defining custom MJML component types using the 'customComponents' option. Each custom component definition receives the editor instance and plugin options.
```typescript
import type { Editor } from 'grapesjs';
import type { ComponentPluginOptions } from 'grapesjs-mjml';
const myDividerComponent = (editor: Editor, { coreMjmlModel, coreMjmlView, componentsToQuery }: ComponentPluginOptions) => {
editor.Components.addType('mj-fancy-divider', {
isComponent: (el) => el.tagName?.toLowerCase() === 'mj-fancy-divider',
model: {
...coreMjmlModel,
defaults: {
name: 'Fancy Divider',
draggable: componentsToQuery('mj-column'),
stylable: ['border-color', 'border-width', 'padding'],
'style-default': { 'border-color': '#ff0000', 'border-width': '2px' },
},
},
view: {
...coreMjmlView,
getMjmlTemplate() {
return { start: '', end: '' };
},
},
});
};
grapesJS.init({
container: '#gjs',
plugins: [grapesJSMJML],
pluginsOpts: { [grapesJSMJML]: { customComponents: [myDividerComponent] } },
});
```
--------------------------------
### mjml-code
Source: https://context7.com/grapesjs/mjml/llms.txt
Returns the current editor canvas serialised as a complete MJML string. This string can optionally be wrapped with `preMjml` and `postMjml` if they were configured during editor initialization.
```APIDOC
## Command: `mjml-code` — Get MJML String
Returns the current editor canvas serialised as a complete MJML string (wrapped in `preMjml`/`postMjml` if set).
```js
// Run the command to get the raw MJML source
const mjmlString = editor.Commands.run('mjml-code');
console.log(mjmlString);
// => '...'
// With preMjml / postMjml wrappers configured:
// editor was initialised with preMjml: '\n' and postMjml: '\n'
const wrapped = editor.Commands.run('mjml-code');
// => '\n...\n'
```
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.