How to embed Gutenberg on a stand alone plugin page

How’s this for cool.

It’s possible to embed Gutenberg into any backend plugin page, with a custom save callback. You can get access to the rendered Gutenberg HTML or raw blocks array to do fun things with.

Embedded Block Editor / Gutenberg in plugin admin page

This is the minimal amount of code to render a functional Gutenberg Block Editor in the backend:

   <div className="embed-gutenberg edit-post-visual-editor">
      <SlotFillProvider>
        <DropZoneProvider>
          <BlockEditorProvider
            value={blocks}
            onInput={onChange}
            onChange={onChange}
            className="embed-gutenberg__wrapper"
          >
            <div className="embed-gutenberg__editor">
              <BlockEditorKeyboardShortcuts/>
              <WritingFlow>
                <ObserveTyping>
                  <BlockList/>
                </ObserveTyping>
              </WritingFlow>
            </div>
            <div className="embed-gutenberg__sidebar">
              <BlockInspector/>
            </div>
            <Popover.Slot/>
          </BlockEditorProvider>
        </DropZoneProvider>
      </SlotFillProvider>
    </div>

The onChange callback can serialize the full html change from the Gutenberg block array using serialize() like this:

  let fullHtml = ''
  blocks.forEach(block => {
    const blockHtml = serialize(block);
    fullHtml = fullHtml + "\n" + blockHtml;
  })

And a default block array for Gutenberg might look something like this:

const defaultBlockArray = [{
  "clientId": "812f33be-af57-475e-9987-af1936fee811",
  "name": "core/paragraph",
  "isValid": true,
  "attributes": {"content": "This is the first Paragraph block", "dropCap": false},
  "innerBlocks": []
}, {
  "clientId": "1e4e538e-5b75-4c93-894f-9bad6aaea746",
  "name": "core/heading",
  "isValid": true,
  "attributes": {"content": "This is a header block", "level": 2},
  "innerBlocks": []
} ]

Leave a Reply

Your email address will not be published. Required fields are marked *