XF 2.4 Tiptap: A new editor for XenForo

2.4 editor flare.webp
Rich text editors are hard. When you drill down into how they actually work, it's a wonder why there are so many of them, and why developers would willingly spend a significant part of their life working on one. At XenForo we have been through ... counts on fingers ... three different rich text editors in our history, so if we're being generous we can at least attest to what a feat of engineering they are and how difficult they can be to get right -- and all we have to do is implement them.

That's no easy feat either, though. We have an increasing number of features that we need from an editor, we have a layer of conversion from HTML to BB code (and back again), and we have an overall user base of millions of members across all of our customers who all seem intent on breaking our editor in weird and wonderful ways. So picking a new editor is fraught with risk and challenges. Sometimes, even when we pick the right editor, it doesn't always stay that way.

Over recent years we've been keeping a close eye on the developments within the rich text editor space and while there are a few interesting projects, there is only one very clear winner, and that is Tiptap.

What is Tiptap?​

Tiptap is a completely modular, open source and headless editor framework. Headless means that there is no provided user interface. Modular means you can enable only the functionality that you need. It is so modular that, technically, you don't even have to enable paragraphs or text (though that might impede its usefulness). It also has a fantastic extension system that allows us to not only create our own extensions, but also extend existing extensions! (more on that later).

Tiptap, which is itself powered by the amazing ProseMirror toolkit, does not simply attempt to decorate input with arbitrary HTML like most rich text editors. Rather, it has a very strict (but extendable) schema made up of Marks and Nodes. Marks are inline formatting (such as bold and italic) and Nodes are block-level formatting (such as paragraphs, quotes, and code blocks).

Your first look​

Strap in, because there's lots to show you. But first, an artist's representation of how it might look in either light or dark styles:

2.4 editor gradient.webp


The overall look and feel of the editor isn't 100% finalised at this point, but the current iteration, as pictured above, does lean into being familiar. One of the notable changes currently is that we have moved the toolbar to the bottom of the editor, making the controls more accessible, particularly on smartphones.

Want it at the top? No problem, that's a single line of CSS to make that happen.

The toolbar is, as ever, managed entirely through the existing editor button manager in the admin control panel, so the toolbar itself can be made as full-featured or as minimalist as you like.

Great for users and power users alike​

For a lot of things, you might not even need to use the toolbar. The brave amongst you might even choose to disable the toolbar entirely, thanks to the simplicity with which many editor features can be used.

As part of the overall schema that powers Tiptap, "input rules" can be defined by developers for each extension, which, in short, are "Markdown-style" editing:



Power users will not only be able to use Markdown-style syntax to produce content - which is enabled for a significant amount of editor functionality - but they will also be able to see the formatting change in real-time.

What you see is really what you get​

In fact, all core editor functions have a visual representation of their content, whereas they might not have previously. We are putting an end to seeing raw BB code syntax in the editor (unless you type it yourself, which still works):



This level of visual clarity for what your final content will look like extends even to code blocks, which are now fully syntax highlighted in the editor. The syntax highlighting is provided by highlight.js. As a result, we have upgraded our BB code syntax highlighting for code blocks to also use highlight.js going forward. We are including more languages (and more relevant languages) by default, and it remains easy to add additional ones to fit your particular niche.



It truly is a "what you see is what you get" experience, and to underline that even more, wait until you see what happens when you paste an embeddable link (best viewed full screen):



A consistent UI powered by XenForo​

As we mentioned earlier, Tiptap is a completely headless editor, meaning we have built the entirety of the UI that you can see. This is now more consistent and more in line with the default XenForo styling than ever. With our previous editors, there was always a hybrid of different UI pieces: some from the editor itself, others that we bolted on. For example, in our current editor implementation there are three distinct UI components we use - Froala pop-ups (insert link), overlays (insert media) and menus (emoji). With the new editor, everything you see is crafted from default XenForo functionality and styling, ensuring consistency:
CleanShot 2024-12-17 at 16.36.31.gif


By the way, the "Insert image" menu of the editor now supports multiple file uploads, including when dragging and dropping!

An exciting experimental editing experience​

While the new UI for the new editor will be very familiar to most, because we now have full control over what the editor can do, we are also experimenting with more innovative methods for writing content. Let's have a sneak peek now at what that might look like (best viewed full screen):



We haven't yet fully decided what form this new editing experience will take. It might be something that is user-selectable, admin-selectable or something that can be enabled as a hybrid with the toolbar. Your thoughts on this approach are welcome!

Extending the editor​

All of this additional functionality is possible, not only with the strong foundations provided by both ProseMirror and Tiptap, but also through an extremely flexible and well thought out system enabling us to build our own functionality. By virtue of that, add-on developers are going to have a great experience bringing new features to our new editor.

For those of you less focused on development, this might not be quite as interesting. But let's just take a look at an example extension that adds some functionality to the editor:



While this is not (currently) shipping as a built-in feature (we haven't even created an associated BB code to render it in posts), we wanted to share it as an example of how easy and intuitive Tiptap is. Here's the sample Tiptap extension code we wrote that powers the functionality seen in the previous video:

JavaScript:
XF.EditorExtensions.registerExtension(({ Node, InputRule }) =>
{
    const inputRegex = /^!!!(highlight|important|success|warning|error)[\s\n]$/

    return Node.create({
        name: 'blockMessage',

        group: 'block',

        content: 'block+',

        defining: true,

        addAttributes()
        {
            return {
                style: {
                    default: 'highlight',
                    parseHTML: element => element.getAttribute('data-style'),
                    renderHTML: attributes =>
                    {
                        return {
                            'data-style': attributes.style,
                        }
                    },
                }
            }
        },

        parseHTML()
        {
            return [
                {
                    tag: 'div[data-type="block-message"]',
                },
            ]
        },

        renderHTML({ node })
        {
            return [
                'div',
                {
                    'data-style': node.attrs.style ?? 'highlight',
                    'class': 'blockMessage blockMessage--iconic blockMessage--' + (node.attrs.style ?? 'highlight'),
                },
                [
                    'div',
                    {},
                    0,
                ],
            ]
        },

        addInputRules()
        {
            return [
                new InputRule({
                    find: inputRegex,
                    handler: ({ state, range, match }) =>
                    {
                        const { from, to } = range
                        const tr = state.tr

                        const node = this.type.createAndFill({
                            style: match[1]?.trim(),
                        })
                        tr.replaceRangeWith(from, to, node)
                    },
                }),
            ]
        },
    })
})

A full breakdown of exactly how this works is beyond the scope of this post, but feel free to spend some time understanding it and the editor docs. If you have existing editor-based add-ons, the great news is that as long as you have some basic understanding of JavaScript, you should be able to produce your own extensions. We are not implementing any additional frameworks; everything is based on vanilla JavaScript.

One more thing...​

The astute amongst you might have already noticed that new lines work differently in the new editor compared to the current one, and there's a very good reason for that. We are pleased to announce that, finally, we are going to be using paragraph (<p>) tags properly starting with XenForo 2.4.

Hitting enter/return in the new editor now creates a new paragraph (with appropriate spacing). This may take a few moments to get used to, as hitting enter/return will now produce new line spacing equivalent to pressing enter/return twice currently. You can insert a "hard break" (producing a <br /> tag) with Shift + Enter. While this might require a brief adjustment, it is now consistent with how many applications and office suite tools work, so we don't expect it to take long.

The correct use of paragraphs doesn't stop with the editor, as we now correctly render content with paragraphs too!

HTML:
<h2 class="bbHeading">A brand new editor experience!</h2>
<div class="bbImageWrapper " title="Happy Season 9 GIF by The Office">
    <img src="https://media3.giphy.com/media/o75ajIFH0QnQC3nCeD/200.gif" class="bbImage">
</div>
<p>You might <b>recognise</b> the concept from applications such as <a href="https://notion.so" target="_blank">Notion</a>. You can add nodes from anywhere!</p>

<p>You can duplicate nodes. And move them around!</p>

<blockquote>
    <p>I've never had so much fun in an editor!</p>
</blockquote>

We haven't even changed the underlying BB code syntax. This is achieved with a brand new BB code parser which intelligently detects the correct boundaries for paragraphs and is able to distinguish between line breaks and paragraphs.

More coming soon!​

Thank you for joining us on this first look into the new editor we're implementing in XenForo 2.4. We're excited to get this in your hands in 2025. In the meantime we have some additional things for the editor that we're still wiring up:
  • Improvements to the developer experience for implementing custom editor functionality, BB code and custom buttons
  • Making use of the new editor elsewhere in XenForo
  • Further improvements to the UI and UX
  • Finalising the introduction of the experimental experience as an option
This will be the final Have you seen...? thread for 2024 and we will be back in the new year with even more to show you as we approach the final stages of this release.
 
The issue with “show who is typing” is the increased server use required.
The issue I have with it is that nobody in any of the forums I manage gives a crap about this useless feature. The rate at which replies are being posted is proof enough the forum is active.

Besides, I really don't care to let anyone know if I am typing. I've always found this a completely useless feature. There are way more other, more important features we could have here. Fluff like this does not belong in a forum.
 
The issue I have with it is that nobody in any of the forums I manage gives a crap about this useless feature. The rate at which replies are being posted is proof enough the forum is active.

Besides, I really don't care to let anyone know if I am typing. I've always found this a completely useless feature. There are way more other, more important features we could have here. Fluff like this does not belong in a forum.
You might not care, I might not care, but I do know forums (have observed first hand) where people haunt the online list waiting for other specific people to read their thread, then reply to it. There is definitely some behaviour at work around if you see someone else replying (especially if it’s a person whose response you care about) you might well wait around for it.

But I think the downsides hugely outweigh the perceived upsides - though I know that Invision is introducing this so it will be a point of comparison and contention in future.
 
The issue I have with it is that nobody in any of the forums I manage gives a crap about this useless feature. The rate at which replies are being posted is proof enough the forum is active.

Besides, I really don't care to let anyone know if I am typing. I've always found this a completely useless feature. There are way more other, more important features we could have here. Fluff like this does not belong in a forum.
Discord and other modern platforms show people do actually care about this feature. Sometimes some modernization is good, even for us old forum folk...

Heck, even iMessage and other communication apps have adopted this modernization for text based conversations.
 
The difference is that Discord shoes you the state in a channel - not something as focused as a topic. That’s where it’s useful in Discord and debatable in a forum.
 
The difference is that Discord shoes you the state in a channel - not something as focused as a topic. That’s where it’s useful in Discord and debatable in a forum.
To be completely honest, I don’t see how that makes much of a difference.
 
To be completely honest, I don’t see how that makes much of a difference.
Of course it does.

In a Discord server with 15 channels, that’s the equivalent of a forum with 15 topics as far as scope of watching goes.

You see the activity across a much broader scale of communication in Discord than you ever would in a forum. Seriously, the comparison is nearer to if you can see someone typing, while on the node list, such that they’re replying to any topic in that node, not scaled down to a single forum topic.
 
Of course it does.

In a Discord server with 15 channels, that’s the equivalent of a forum with 15 topics as far as scope of watching goes.

You see the activity across a much broader scale of communication in Discord than you ever would in a forum. Seriously, the comparison is nearer to if you can see someone typing, while on the node list, such that they’re replying to any topic in that node, not scaled down to a single forum topic.
I am still not seeing why it truly matters whether or not this feature is on a channel or a thread in all retrospect. I understand what you’re saying, but at the end of the day - I don’t really think it makes much of a difference. More active forums have certain “hot” threads that can become very active during the day, all this feature would do is add more liveliness to the forum.

Also it can easily be an option. If you guys don’t like features that add to the human element of communication through text, then just keep it turned off. Or enable it for certain nodes.
 
Because a channel is not equivalent to a single forum thread! That’s the whole thing about Discord - a single channel ebbs and flows with a variety of topics like one long single conversation.

Your forum likely does not have individual megathreads that meander and change, which is functionally how Discord works.

Go try a Discord thread (in their forums feature) and see how effective that is for watching discussion (even on a modestly busy server, it tends to be less common than talking in the main channels)

Like I said, the nearest analogue in XF to a Discord channel is an entire node, not a single topic in one.
 
Because a channel is not equivalent to a single forum thread! That’s the whole thing about Discord - a single channel ebbs and flows with a variety of topics like one long single conversation.

Your forum likely does not have individual megathreads that meander and change, which is functionally how Discord works.

Go try a Discord thread (in their forums feature) and see how effective that is for watching discussion (even on a modestly busy server, it tends to be less common than talking in the main channels)

Like I said, the nearest analogue in XF to a Discord channel is an entire node, not a single topic in one.
Again, I understand what you are saying, but I dont think what you are presenting with Discord as being a limiting factor to more modernization human interaction features such as this for a forum text based discussion platform.

Even iMessage does this now a days as standard, showing when another human is typing.... along side majority of other instant message applications.

A forum platform can be used in many ways, you are silo'ing the usecase to claim more modernization features are "useless", when I am telling you first hand on our Xenforo install - we have certain weekly coordination threads for certain flight events that become very active on certain days of the week leading up to the mission. This feature would add more human liveliness to the text streams within said threads. We even have a Intel thread that houses all of our mission updates, intel reports, after action reports ect... just because its a "thread", makes no real difference as opposed to the dialogue that we also have in our Discord channel.

I am trying to offer modernization ways to keep Forums up to the same standard, if not to succeed these other instant message platforms that the new generations are attracted to. The arguments you are making is what will keep forum platforms stagnant, and unable to grow and evolve for the future years to come IMO.
 
There is a maximum message length limitation in the admin panel. But there is no native character count for the editor either. And we are talking about modernisation. There is a long way we should walk :)
 
No, I’m saying that this specific feature in this specific context is questionable, and you keep bringing false equivalence to the party and assuming my issue is not what you think it is.

Let’s take your example of iMessage (and FB Messenger etc etc). This is a 1:1 or 1:group message format where a message will likely prompt a reaction from another in the conversation, and chances are it will be a timely one. Thus, having that feedback is useful (outside of the meme of “typing… pause… typing… pause… typing… pause… then the message is just ‘OK’”) because it’s targeted and contextually useful. This also holds true for Slack where the locality inside a channel is useful, and the locality in a single thread is useful if the response is timely because it’s a current conversation.

In a Discord channel, the spread of people who will see the whole conversation and reply in a timely fashion is typically wider than the number of people who happen to be in a specific topic, waiting for an answer to that specific topic.

Now if you want to talk about displaying that on the node listing of topics, we have something to talk about.

Alternatively if you’re going to talk about replies in a forum broadly being shorter and more chat-like (where a response being timely is more likely), we have something to talk about.

But ascribing these behaviours to a forum is… possibly misleading for any message more than a couple of lines.

We will see once Invision 5 is out, they’re supposed to have that feature, and we can see how well it works in the real world of forums rather than spitballing how we think it might play out based on our respective experiences of forums. I do not believe it will be the stimulus it is being suggested, because the locality and timeliness just don’t align.
 
No, I’m saying that this specific feature in this specific context is questionable, and you keep bringing false equivalence to the party and assuming my issue is not what you think it is.

No, I completely do understand what you are explaining here. I just don't believe its fair to silo the usecase for this type of feature.

Let the admin decide then if it should display "who is typing..." on the node list, and/or within the thread then. Either way, it is a modernization feature that majority of other platforms are adopting to add more human liveliness to the platform. And there is reasoning for that... regardless if old school forum folk (I am one of them myself) think otherwise.
 
Back
Top Bottom