Jump to content
View in the app

A better way to browse. Learn more.

Invision Community

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

IC5: The New Editor

In 2024, a secure WYSIWYG Editor has become a complex intricate thing.

Copy/paste bundle files have largely been phased out in favor of complicated NPM repos and build tools. What was more or less just "HTML Manipulation" has evolved to abstract content models with dynamic rules on how to actually render the content to HTML. Then, for kicks, throw in the requirement that this editor needs to work in non-standard cases like the drag and drop page builder and live topics. The solution for Invision Community 5 is a new, custom, state of the art Editor built using ReactJS and Tiptap.

In this article, I'll cover high level advantages, technical highlights and what's possible with 3rd party extensions. 

If you want to know more about the editor functionality, then see my other blog here.

This story begins after we switched to CKEditor5 over a year ago. It is a decent product, but it had several serious limitations in a distributed platform like Community. We compared just about every editor currently on the market, and even considered building an editor completely from scratch, and ultimately landed on creating a custom editor using ReactJS and Tiptap.

 

A lightweight package

The v5 editor bundle size is small, coming to about 2mb in total (and it's split into separate chunks loaded ad-hoc, each one cached in the browser, so in practice much less data actually "loads"). After optimizing and tweaking CKEditor5, the smallest we could get it was over 50mb; now some build tool experts could probably wrangle that cke package to a smaller size, but I doubt it'd come anywhere close to Tiptap with all the features we added.

It's also worth noting that, during operation, Tiptap had by far the lowest impact on browser memory consumption, and stubborn memory leaks never came up with this architecture. Part of this comes from taking advantage of ReactJS's stateful nature, but I think the most significant thing is that Tiptap doesn't have loose logic hanging around.

 

How a modern WYSIWYG works (the short version)

As I previously alluded to, editors today don't directly manipulate HTML at all. Instead, they store a Content Model according to a Schema.

Different platforms may use different terms, but the content schema consists of the following Entities

  • Nodes - Actual containers to put content in. Think blockquotes, headings or lists. Nodes are then stored in the document in a tree
  • Text and Inline Nodes - Text is, well, text. It is exclusively just a string of characters; one way to think of it is, if it can go in a text message, it's text. Inline nodes, on the other hand, are not true "characters" but displayed inline with characters. Think custom emoticons and mentions.
  • Marks - Styles and/or data that is applied over a range of text. Marks are similar to Nodes except that marks can overlap. For example, it if text is italic and bold, it makes no difference if it's bold inside italic or vise versa. Moreover, it it most accurate to simply say that text is just both italic and bold; this data is stored in Marks. In old editors, like CKEditor4, this was often just thrown into a "style" attribute which led to all sorts of issues and overhead processing. (These are not what CKEditor calls "marks" FYI, they call this concept "text attributes", in case anyone has existing CKE knowledge)

All the above entities rely on Converters to generate them from HTML and then reconvert back into HTML. When the editor starts, it uses those converts to convert the initial data into the Content Model. Then, any change is made to the Content Model directly, which is continuously being converted back into HTML for the user to see.

Security and Consistency

The Schema and architecture add a layer of complexity but provide much better security, consistency and reliability because it only allows whitelisted content structures. For example, if I inserted something with the attribute style="color:white; transform: rotate(45deg)", the transform and color will be stripped out unless there's an existing converter to convert it to a Mark.

Another example good example is simple bold styling: I can define several converters to parse the bold Mark: one for <b> tags, one for <strong> and one for style="font-weight: bold", and have them all convert back into a <strong> tag.

Lastly, this gives us the assurance that, for any style, there is a user interface to manipulate and manage it. For this reason, source editing was removed because you won't ever need to fall back to source editing.

I could go on for hours (seriously, don't get me started) but that's more than enough context to understand the rest of this article.

 

Extending the Editor in Invision

Another limitation of CKEditor5 in a distributed platform, where individual admins may want to customize, is that all Plugins have to be present at build not at runtime. This would pretty much mean no extending the editor, just rearranging the toolbar and flipping certain builtin features on and off.

Fortunately, in Tiptap we were able to extend their internal node, mark and extension APIs. We'll have a more complete dev guide, but essentially all nodes, marks and extensions, which I'll just call "extensions" collectively, are rolled into the existing app system. There are 2 reasons we did this instead of just "buttons" like Invision 4, where you can just upload the CKEditor4 plugin zip file:

  1. It relies on using PHP to parse JavaScript to get things like the button title and stuff. If you create a valid plugin but define things in a slightly different way than expected, such as adding the name to the wrong line in the file, the plugin upload fails.
  2. Plugins/extensions are not buttons. Many CKE plugins have multiple buttons and many have none. This make management difficult because sometimes there isn't a button to remove and you have to reset all plugins, or you want to remove just one and 5 others disappear with it. Also, mostly all plugins add a new type of content; this type of content needs to be whitelisted

Now, you may be thinking, "like the editor itself, won't the server side HTML Parser will strip any content that is not whitelisted"? Well, the answer is yes and we added a new AdminCP Dev Center tool to create Parser Whitelist Rules inside Invision Community Apps (again more on all this later). With the coupling of the Parser Whitelist and Editor Extensions, admins can rest assured that their editors will just "work" when you install Extensions.

If you want to prematurely prepare to create Invision Community 5 Editor Extensions, have a look at Tiptap's Dev API Documentation, specifically the methods Node.create(), Mark.create() and Extension.create(). We've added wrappers for those three methods, in addition to an interface to add and position buttons in the toolbar.

Please let me know if you have any questions!

User Feedback

Recommended Comments

derpunker

Clients

We've added wrappers for those three methods, in addition to an interface to add and position buttons in the toolbar.

Are there any further details regarding this wrappers?

I have checked the development center and also the code, but didn't find any hint where and how to add an editor extension.

Any hint is welcome. :-)

Thanks in advance.

hjmaier

Clients

Is there an update of the developer guidelines? I did not find any.

Here you have some options in the editor (like spoiler) which I don't have. Maybe you can share how you did it, so I can add what I want myself?

25 minutes ago, hjmaier said:

Is there an update of the developer guidelines? I did not find any.

Here you have some options in the editor (like spoiler) which I don't have. Maybe you can share how you did it, so I can add what I want myself?

We're testing editor changes for an upcoming update. Code block and Spoiler buttons are part of that.

Indy Dave

Clients

How about adding vertical alignment options in tables? Right now it seems to default to a 'justified' setting with no way to change.

Square Wheels

Clients
21 hours ago, Indy Dave said:

How about adding vertical alignment options in tables? Right now it seems to default to a 'justified' setting with no way to change.

I think tables was a nice addition, but they are very limited, and very hard to use.

Indy Dave

Clients
On 8/23/2025 at 3:07 PM, Square Wheels said:

I think tables was a nice addition, but they are very limited, and very hard to use.

Agree - happy for the effort, really hoping for some greater functionality.

PTiCA1

Clients

Is there at least an option to edit icon positions? Or is the editor not editable at all?

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.