Episerver + TinyMCE + React = uh oh!

Published on in Episerver, JavaScript and React

Thoughts on how to efficiently use React to render Episerver blocks embedded in TinyMCE fields.

This week at work I was pondering how to mount a React component to a <div> whose contents are defined using the dangerouslySetInnerHTML prop. Sounds ugly, and it is, but hear me out:

Episerver (.NET CMS) uses the TinyMCE editor for rich text editing and allows drag-and-dropping "blocks" (reusable pieces of content) into TinyMCE fields. By default, blocks are rendered as empty <div>s, like this (simplified example):

<p>Normal content</p>
<div data-epi-block-id="123"></div>
<p>
  More normal content.
  Block inside a paragraph:
  <div data-epi-block-id="456"></div>
  And more text.
</p>

Now, I could:

  1. render the HTML as-is,
  2. retrieve the blocks' data using Ajax requests after the component has been mounted,
  3. and then mount other React components to the <div>s.

But I don't want to, because that would be slow and incur an extra HTTP request per each block.

I'm thinking of including the blocks' data in the HTML before sending it to the front-end:

<p>Normal content</p>
<div data-epi-block='{ "id": 123, "blockType": "FooBlock", "title": "Hello block", ... }'></div>
<p>
  More normal content.
  Block inside a paragraph:
  <div data-epi-block='{ "id": 456, "blockType": "BarBlock", "title": "Another block", ... }'></div>
  And more text.
</p>

Then I could use JSON.parse() to turn those JSON attributes into props objects. Mounting React components to those <div>s could be done as suggested in these Stack Overflow answers:

Like I said: ugly! And still just a theory. But necessary. We shall see later if this feasible.