Adding custom blocks to GrapesJS builder


I am trying to configure the GrapesJS builder with custom blocks. This possibility is mentioned in the docs:

GrapesJS comes with a set of built-in blocks, in this way you’re able to build your templates faster. If the default set isn’t enough you can always add your own custom blocks.

from Mautic docs

Unfortunately, I was not able to find any more information on how to approach this. Here is a short tutorial on adding custom code block, but I am not sure how related this is to my problem. I also found a message on Slack that asked about adding custom blocks through a template.

Obviously, I can fork Mautic and build it into the GrapheJS plugin directly, but I was wondering what would be the least intrusive way of doing it.

Any help is appreciated!

Your software
My Mautic version is: 4
My PHP version is: 7.4

Hi, you could have a look at GitHub - mautic/grapesjs-preset-mautic: GrapesJS preset configuration for the Mautic editor as they add mautic blocks to the grapejs editor this way

Thanks, jonathandhn!

There were additional requirements that made that approach infeasible. In particular, we wanted to give our designers full control, meaning they needed to be able to upload block definitions themselves. Our approach looks like this:

  1. Use a one-time patch for the Mautic GrapesJS plugin.
  2. Upload block definitions within the theme archives using the standard GUI.

GrapesJS plugin patch

Put this somewhere after the initialization of the editor in the GrapesJS plugin, for example at the end of the launchBuilderGrapesjs function in builder.js.

// Get the GrapesJS editor.
const editor = ...; // depends on snippet location

// Find the theme ID from the selection field.
const themeSelect = document.getElementById("emailform_template");
if (themeSelect) {
  const themeName = themeSelect.value;

  // Load the blocks.json that contains the GrapeJS block config.
  const url = `/themes/${themeName}/blocks.json`;
  fetch(url).then((res) => res.json()).then((blocks) => {
    // Replace default blocks with loaded blocks.
    const bm = editor.BlockManager;
    for (const id in blocks) {
      bm.add(id, blocks[id]);
  }).catch(() => {
    // Ignore if there is not blocks.json for this theme.

Upload block definitions

Themes can now optionally include a blocks.json file that looks something like this:

  "text": {
    "label": "Text",
    "content": "<mj-text font-size=\"17px\">This is a paragraph.</mj-text>",
    "attributes": {
      "class": "fa fa-camera-retro"
  "button": {
    "label": "Button",
    "content": "<mj-button>Click me now</mj-button>",
    "attributes": {
      "class": "gjs-fonts gjs-f-button"
1 Like

@adiux something that might be of interest for the builder here?