Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions content/guides/01.data-model/4.rich-text.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,5 @@ Two things to keep in mind:
## Next Steps

Read about the [WYSIWYG interface options](/guides/data-model/interfaces#wysiwyg), the [supported HTML and normalization behavior](/releases/breaking-changes/version-12#wysiwyg-editor-rebuilt-on-tiptap), and [keyboard shortcuts](/getting-started/accessibility) for the editor.

To add your own nodes, marks, and toolbar buttons, build a [rich text extension](/guides/extensions/app-extensions/richtext). These extensions depend on the Tiptap version that ships with Directus, as described in the [Tiptap version policy](/guides/extensions/app-extensions/richtext#tiptap-version-policy).
8 changes: 8 additions & 0 deletions content/guides/09.extensions/3.app-extensions/0.index.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ App Extensions extend the functionality of the Data Studio.
class: col-span-3
---
:::

:::u-page-card
---
title: Rich Text
to: '/guides/extensions/app-extensions/richtext'
class: col-span-3
---
:::
::


Expand Down
74 changes: 74 additions & 0 deletions content/guides/09.extensions/3.app-extensions/7.richtext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
stableId: c00df192-7fcb-457e-8fc8-fc05b853f88a
title: Rich Text Extensions
description: Rich text extensions add Tiptap nodes, marks, and toolbar buttons to the WYSIWYG interface.
navigation:
title: Rich Text
---

Rich text extensions add [Tiptap](https://tiptap.dev) nodes, marks, and toolbar buttons to the [WYSIWYG interface](/guides/data-model/interfaces#wysiwyg). A field uses an extension only when you select it in the interface's **Extensions** option.

## Tiptap Version Policy

A rich text extension uses the copy of Tiptap that ships with the Data Studio. The extensions SDK does not bundle the shared Tiptap packages, so the editor and your extension use the same ProseMirror classes. ProseMirror checks objects by class, so objects from a second copy of ProseMirror fail these checks and the editor behaves incorrectly.

This makes the Tiptap version part of the extension API. A new Tiptap major version can break every installed rich text extension. Directus shares `vue`, `vue-router`, `vue-i18n`, and `pinia` with app extensions in the same way.

### Shared Tiptap Packages

Import the following packages directly in your extension. The extensions SDK marks them as external when it builds, so your bundle uses the Data Studio's copy and does not include them.

- `@tiptap/core`
- `@tiptap/vue-3`
- These `@tiptap/pm` subpaths: `commands`, `dropcursor`, `gapcursor`, `history`, `keymap`, `model`, `schema-list`, `state`, `tables`, `transform`, and `view`. For example, `@tiptap/pm/keymap`.

Each `@tiptap/pm` subpath re-exports one ProseMirror package. For example, `@tiptap/pm/keymap` re-exports `prosemirror-keymap`. When your code or a package you install imports a ProseMirror package behind a shared subpath by its own name, the extensions SDK changes the import to that subpath. So you can install Tiptap packages that use ProseMirror, such as `@tiptap/extension-table`. The SDK bundles the code of the package itself, but it uses the Data Studio's copy of ProseMirror.

The Data Studio does not use `@tiptap/pm/changeset` or `@tiptap/pm/inputrules`, so the extensions SDK bundles them into your extension. This is safe. They do not contain ProseMirror classes or plugin keys that the editor checks, and their own ProseMirror imports go to the shared subpaths.

If you install other Tiptap packages, use a version from the same Tiptap major as Directus.

### Version Guarantees

| Directus | Tiptap |
| -------- | ------ |
| 12.x | 3.x |

- Directus pins the Tiptap major version. Tiptap minor and patch updates can ship in any Directus release.
- A new Tiptap major version ships only in a new Directus major version.
- The [breaking changes](/releases/breaking-changes) page for that Directus version lists the Tiptap upgrade.

### Set the Host Range

The `host` field in your extension's `package.json` declares the Directus versions it supports. Set it to a caret range on the Directus version you build against.

```json
"directus:extension": {
"type": "richtext",
"path": "dist/index.js",
"source": "src/index.js",
"host": "^12.4.0"
}
```

A caret range stops at the next major version. When a Directus major version upgrades Tiptap, your range no longer matches it.

The Marketplace compares `host` with the project's Directus version. When the range does not match, the extension's page shows **Compatibility not guaranteed**.

::callout{icon="i-lucide-triangle-alert" color="warning"}
Directus does not check `host` when it loads an extension. An extension that you install manually loads on any version. Read the breaking changes before you upgrade a project that uses rich text extensions.
::

### Upgrade After a Tiptap Major Version

When a Directus major version upgrades Tiptap, update your extension before your users upgrade.

1. Read the breaking changes for the new Directus version and Tiptap's upgrade notes.
2. Update the Tiptap APIs your extension uses.
3. Build the extension and test it on the new Directus version.
4. Set `host` to the new major version, for example `^13.0.0`.
5. Publish the update as a new major version of your extension.

## Next Steps

Read about [publishing to the Marketplace](/guides/extensions/marketplace/publishing), the [WYSIWYG interface options](/guides/data-model/interfaces#wysiwyg), and [custom formats](/guides/data-model/rich-text) for the editor.
Loading