Using EditorJS to Implement a Custom Rich Text Editor in AEM

Jorge Chércoles, January 12, 2023

The out of the box components provided by Adobe Experience Manager (AEM) cover a large set of use cases. With the application of styling, they let authors share content they want site visitors to see. But, sometimes you need to customize dialogs to expand their capabilities. 

One example is the AEM Rich Text Editor (RTE). Though the out of the box RTE does allow the user to do quite a lot with text including create tables, hyperlink text and  add bullets to lists, the features allowed don’t always meet the needs of authors or provide the flexibility an author needs to achieve their content goals. They may want to add images, apply more styles, adjust how tables appear and more. When such needs arise, customization is required. As a proof of concept, I created a custom RTE for AEM that makes it easier to expand its features.

Customizing an out of the box AEM Dialog can be a complicated task, but as I'll show you, it can be done with the right approach. In case you’re not familiar with how to do this, you start by creating a Component that renders an <input>. The dialog will automatically save the input value in the CRX with the specified input name as a property. Apply styling and javascript to the Component by embedding it in the cq.authoring.dialog clientlib.

Replacing the AEM RTE with EditorJS

We all can agree that AEM RTE is not the best in terms of ease of customization. There are a few plugins on the web that can extend the functionality of the editor, but creating new ones is very difficult.

In most cases, the AEM editor itself is enough, and a little more customization can be achieved thanks to these plugins: AEM - Touch UI - RTE HTML Element Selector, Custom Style Plugin & Color Picker Plugin.

But, what happens if we want to go one step further?

The AEM RTE API is not documented, so extending it is very complicated. That is where other Rich Text Editors shine.

Using the method above, at 3|SHARE we created a proof of concept (POC) of a custom rich text editor as a replacement for the AEM RTE.

EditorJS

For this POC, we chose EditorJS.

I’ll show the pros and cons of the workspace below. It isn’t perfect for AEM but it was the simplest that we found for creating our POC.

We wanted to test how simple it was to create custom plugins that met the current AEM RTE and improve it considerably, and so far, it worked!

The documentation around creating plugins contains a lot of examples available as open source that you can use for reference.

Pros of EditorJS in AEM

  • Highly customizable: you can create any kind of plugin. Some of the plugins available are integrated with a backend to fetch resources. You can imagine what you can achieve.
  • Multifield: in this implementation, we took consideration of every place in author where the RTE can be placed. As a result, you can place this component as a standalone input or multifield in a component dialog, page property tab or content fragment.
  • Documentation: its API is documented and there are many examples on the web
  • UI: modern interface, which gives AEM a bit of freshness
  • Organized: there is no longer a fixed header with 2 or 3 rows of tools. EditorJS splits their tools in three categories:
    • Block plugins: these correspond with every “block” we add.
    • Inline plugins: only applies to the selected text. A popup will display when you select some text.
    • Tune plugins: these plugins are different from the rest. They are generic plugins that modify the block, but are not related to the block itself.
  • Native components: using a trick, we can use native components such as the page picker or asset picker from AEM.
  • Sling Resource Merger: we can take advantage of the AEM Sling Resource Merger when defining the XML configuration for the component. Not really a pro, but it is good to have it!

Cons of EditorJS in AEM

Custom work: whenever a new block or tune plugin is added to the editor, some work has to be done, to convert the JSON output to HTML.
There is a package (editorjs-html) that handles JSON to HTML conversion, but every new block plugin has to provide a custom formatter.
The same happens with the tunes; every formatter has to support them.

Migrations: due to the JSON saved data format, plain HTML cannot be saved directly to the CRX property. The value in AEM stores both the JSON and the HTML exported.

Extensibility: right now, this POC cannot be extended if installed as a dependency in other projects.

Built In tools

In this POC we used some tools that are installed in the EditorJS by default and then manually coded some. You’ll find that there are many options for plugins so you can create an RTE that works best for your authors. You can even create your own plugins. A few examples of what we did are listed below.

For the block plugins, we installed Header and Table, and coded:

  • Nested List: even though a plugin exists for this, the markup didn’t correspond to the actual html exported. The ordered bullets were placed using css, making it almost impossible to customize.

  • Image: adding images in a rich text editor is a must. This plugin provides the user with a button where they can drag the asset from the AEM side panel or click it in order to open the native AEM asset picker.

For the inline plugins, we coded:

  • Link: similar to the image plugin, this one provides the user with the native AEM page picker component, so they can select the specific page from AEM as well as the link target property.

For the tune plugins, we coded:

  • Text Alignment: support for text alignment left, center or right.

  • Classes: one of the most common requirements with the AEM RTE, is to provide a class picker for the desired element.
    This plugin allows the user to pick one style per block, a class will be added to the html wrapper.

Conclusion

As we can see, there is still a lot of work before having a production ready solution.

We are still missing features from the AEM RTE and it is not extensible when installed as a dependency. But so far, we managed to implement a custom functional rich text editor in AEM.

This opens a new set of opportunities for customization, not only for the RTE, but any kind of component required that is not available by default or needs a better UX.

If you have questions about this subject or anything else related to AEM development or server management, contact us at 3|SHARE. We'll be happy to chat about how we can help!

Topics: Adobe Experience Manager, Development, AEM

Jorge Chércoles

Jorge Chércoles is an AEM Backend Developer at 3|SHARE. His passion is coding whether that is at work or outside of work. He loves that it gives him the ability to create things out of nothing. At 3|SHARE, Jorge enjoys the work environment and independence he has while doing his job. He is an Adobe Certified Expert having earned the Adobe Experience Manager Sites Developer certification.