GrapesJS / mjml

Newsletter Builder with MJML components in GrapesJS
http://grapesjs.com/demo-mjml.html
BSD 3-Clause "New" or "Revised" License
648 stars 229 forks source link

grapesjs-mjml plugin no longer works with grapesjs 0.19.4 (and up) and React #297

Closed Drew-Daniels closed 2 years ago

Drew-Daniels commented 2 years ago

My team has previously used grapesjs v0.18.4, grapesjs-mjml v0.6.6 and react together without issue. However, since the upgrade we made from 0.18.4 to 0.19.5, the 3 no longer work together. I have created a simple example to illustrate the issue we're seeing.

Summary:

When using grapesjs v0.19.4 and up, whenever I try to drag a Section component onto a blank Canvas, I receive this warning:

{
    "errors": [
        "Target collection not found",
        "Component not draggable, acceptable by [[data-gjs-type=mj-body], [data-gjs-type=mj-wrapper]]"
    ],
    "model": {
        "tagName": "mj-section",
        "type": "mj-section"
    },
    "context": "sorter",
    "level": "warning"
}

Video:

v0.19.4 and up: screen-capture (1).webm

v0.18.4: screen-capture (2).webm

Here is my setup:

index.js:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

App.js:

import Builder from './Builder';

function App() {
  return (
    <div className="App">
      <Builder />
    </div>
  );
}

export default App;

Builder.js:

import { useState, useEffect } from 'react';

import grapesjs from 'grapesjs';

import 'grapesjs/dist/css/grapes.min.css';

import config from './config';

export default function Builder() {
  const [editor, setEditor] = useState(null);

  useEffect(() => {
    if (!editor) {
      const newEditor = grapesjs.init(config);
      setEditor(newEditor);
    }
  }, [editor])

  return (
    <div id="gjs" style={{ overflow: 'hidden', height: '100%' }}>
      <mjml>
        <mj-body />
      </mjml>
    </div>
  )
}

config.js:

import grapesJSMJML from 'grapesjs-mjml';

const config = {
  plugins: [grapesJSMJML],
  container: '#gjs',
}

export default config;

This appears to only be an issue when using grapesjs v0.19.4 or higher along with the grapesjs-mjml plugin.

What I have tried:

From:

style: 'width: 100%; min-height: 100%',

To:

style: ' width: 100%; min-height: 100vh; margin:0 auto;',
useEffect(() => {
  if (!editor) {
    const newEditor = grapesjs.init(config);
    newEditor.addComponents(`
    <mjml>
      <mj-body></mj-body>
    </mjml>
    `)
    setEditor(newEditor);
  }
}, [editor])

Nothing works, the only thing that makes a difference is downgrading to the previous version, which we do not want to do because of the XSS vulnerabilities that come with doing so.

Drew-Daniels commented 2 years ago

Here is the example I used for testing if anyone would like to try recreating this: https://github.com/Drew-Daniels/grapesjs-react-bug

Drew-Daniels commented 2 years ago

After looking through the grapesjs release notes again, I noticed a couple changes in v0.19.4 that I believe may have affected the grapesjs-mjml plugin's ability to work with React. The screenshots below are taken from the v0.19.4 release notes:

heroic commented 1 year ago

Still getting this with grapejs 0.20.4 and mjml 1.0.4

@Drew-Daniels solution of adding

editorRef.current.onReady(() => {
      editorRef.current!.DomComponents.clear();
      editorRef.current!.setComponents(
        '<mj-body><mj-wrapper></mj-wrapper></mj-body>',
      );
    });

works

rogueturnip commented 12 months ago

This has had a temporary fix for a long time. wondering if anyone knows if this is the final solution?