GrapesJS Starter

HTML

<script src="https://unpkg.com/grapesjs"></script>
<link rel="stylesheet" href="https://unpkg.com/grapesjs/dist/css/grapes.min.css">
<script src="https://unpkg.com/grapesjs-blocks-basic"></script>
<div id="gjs">
    <div class="header gjst-ghost" style="height:50px;background-color:orchid;">header</div>
    <div class="menu-wrapper gjst-ghost-parent" style="display: flex;">
      <div class="side-menu gjst-ghost" style="background-color: khaki; min-height: calc(100vh - 100px); width: 18%;">side menu</div>
      <div id="the-content" class="gjst-content" style="min-height: calc(100vh - 100px); flex-grow: 1;">
        <h1 style="max-width:80%;margin:1rem auto;">Title</h1>
        <p style="max-width:80%;margin:1rem auto;">Content</p>
      </div>
    </div>
    <div class="footer gjst-ghost" style="height:50px;background-color:aquamarine;">footer</div>
  </div>

CSS

body, html {
  margin: 0;
  height: 100%;
}

Babel + JSX

grapesjs.plugins.add('grapesjs-test', editor => {
  const domComponents = editor.DomComponents
  const defaultType = domComponents.getType('default')
  const Component = defaultType.model

  domComponents.addType('gjst-ghost', {
    model: Component.extend(
      {
        defaults: {
          ...Component.prototype.defaults,
          badgable: false,
          copyable: false,
          draggable: false,
          droppable: false,
          highlightable: false,
          hoverable: false,
          movable: false,
          removable: false,
          stylable: false,
          propagate: ['badgable', 'droppable', 'highlightable'],
        },
        toHTML() {
          return ''
        },
      },
      {
        isComponent(element) {
          if (element.classList && element.classList.contains('gjst-ghost')) {
            return { type: 'gjst-ghost' }
          }
          return false
        },
      }
    ),
    view: defaultType.view,
  })

  domComponents.addType('gjst-ghost-parent', {
    model: Component.extend(
      {
        defaults: {
          ...Component.prototype.defaults,
          badgable: false,
          copyable: false,
          draggable: false,
          droppable: false,
          highlightable: false,
          hoverable: false,
          movable: false,
          removable: false,
          stylable: false,
          propagate: ['badgable', 'highlightable'],
        },
        toHTML() {
          return ''
        },
      },
      {
        isComponent(element) {
          if (element.classList && element.classList.contains('gjst-ghost-parent')) {
            return { type: 'gjst-ghost-parent' }
          }
          return false
        },
      }
    ),
    view: defaultType.view,
  })

  domComponents.addType('gjst-content', {
    model: Component.extend(
      {
        defaults: {
          ...Component.prototype.defaults,
          badgable: false,
          copyable: false,
          draggable: false,
         ...