Invalid schema handling in Tiptap

Editor

Content integrity can be a significant challenge in collaborative editing environments. Think of a scenario where users with different versions of an app are trying to edit the same document. Or a scenario common to single-page applications: some users keep their browser tabs open for long periods of time without refreshing, while others always have the latest editor version after a recent page load.

In both cases, a user with a newer version is creating content with features that are not available to others. When a user with an older version tries to access this document, how do we prevent data loss, maintain document structure, and ensure a smooth user experience?

This is where invalid schema handling becomes important. It allows developers to gracefully manage situations where the content structure doesn't match the editor's expectations, preventing issues like data corruption, unexpected content stripping, or editor crashes.

Whether you're building a note-taking app, a content management system, or any application with rich text editing capabilities, understanding and implementing proper schema handling can significantly improve your application's reliability and user experience.

Introducing content checking

Tiptap has an option called enableContentCheck. When set to true, this feature activates a mechanism to validate content against the schema derived from your registered extensions. This is particularly useful for catching and responding to content errors before they cause issues in your application.

Enable content checking

To enable this feature, simply add the enableContentCheck option when initializing your Tiptap editor:

new Editor({
  enableContentCheck: true,
  // ... other options
})

The contentError event

When content checking is enabled, Tiptap will emit a contentError event if the initial content provided during editor setup is incompatible with the schema. This event provides you with valuable information to handle the error appropriately.

Handle contentError events

You have two options for handling these events:

Either you can use the onContentError callback:

new Editor({
  enableContentCheck: true,
  content: potentiallyInvalidContent,
  onContentError({ editor, error, disableCollaboration }) {
    // Your error handling logic here
  },
  // ... other options
})

Or you can attach a listener to the contentError event:

const editor = new Editor({
  enableContentCheck: true,
  content: invalidContent,
  // ... other options
})

editor.on('contentError', ({ editor, error, disableCollaboration }) => {
  // Your error handling logic here
})

A note on content types

It's important to note that Tiptap's content checking is 100% accurate for JSON content types. However, when working with HTML content, there may be some limitations. While Tiptap does its best to alert on missing nodes, certain mark-related issues might be missed in some situations.

How you handle schema errors will depend on your specific application and requirements. However, here are some general recommendations:

For non-collaborative editing

If you're not using collaborative editing features, the default behavior of stripping unknown content may be sufficient. This keeps your content in a known valid state for future editing.

For collaborative editing

When using collaborative features, it's crucial to handle content errors to prevent synchronization issues. Here's an example of how you might handle a content error in a collaborative environment:

onContentError({ editor, error, disableCollaboration }) {
  // Disable collaboration to prevent syncing invalid content
  disableCollaboration()

  // Prevent emitting updates
  const emitUpdate = false

  // Disable further user input
  editor.setEditable(false, emitUpdate)

  // Notify the user about the issue
  notifyUser("An error occurred. Please refresh the application.")
}

This approach:

  1. Disables collaboration to prevent syncing invalid content
  2. Prevents updates from being emitted
  3. Disables the editor to prevent further user input
  4. Notifies the user about the issue