prosemirror
Introduction
Clean APIs. Consistent content. Limitless frontends.
A ProseMirror-based rich text editor for Drupal, providing a modular, extensible foundation for rich text editing.
Compared to CKEditor:
- ProseMirror provides better headless, decoupled, and omnichannel content editing capabilities.
- ProseMirror is very easy to extend with custom elements and marks by simple configuration.
- ProseMirror supports custom component-based elements like info boxes, code blocks, accordions, or content columns.
- ProseMirror is fully open-source with no dual license and no restricted features.
Why is ProseMirror better suited for headless, decoupled, and omnichannel publishing?
The ProseMirror module stores content as structured data instead of HTML. While HTML is simpler for content that's used strictly within Drupal, it's very limiting for use cases outside of Drupal:
Not every channel supports CKEditor's HTML
Problems
- A renderer in a native app must be able to map elements and marks to natively constructed components.
- A Next.js app developer may require more control over how to display certain elements.
- Emails require a very specific format to be displayed correctly across email apps, even though they technically also use HTML.
- Digital signage may not be able to display links.
- Social media platforms don't allow HTML.
Solution
ProseMirror's structured data makes it easy for developers to take full control over the display by mapping elements and marks to components for any platform, application, and use case.
You can render it inside a Next.js app, generate email newsletter HTML, and instantiate native app components.
Links rely on Drupal's routes and navigation
Problems
- A React developer may want to use different path-based routing than what Drupal uses internally.
- A native app may not be aware of path-based routing at all and require links to be resolved by content IDs and internal navigation.
- Digital signage may not allow links at all and may prefer displaying referenced content differently.
Solution
ProseMirror's structured data makes it easy to decide in the frontend how to render and open links.
Media and image handling
Problems
- Static HTML tags make it difficult to take control of media embedding and rendering in frontends.
- Images use relative file system URLs that may not work when used outside of Drupal.
- Images and media may have to be optimized per application and device and not with Drupal's static image styles.
- Images and media may have to be cached on a native device for displaying content natively and for offline availability.
Solution
ProseMirror's structured data makes it easy to decide in the frontend how to request, optimize, cache, embed, and render images and other media assets.
We recommend using CDNs to add image optimization options for frontend development to work independently of Drupal's image styles.
Migrating from CKEditor
The ProseMirror module ships with a default renderer for HTML, so from an editor perspective it doesn't behave any differently, and you don't have to write any custom code for displaying rich text either. The biggest difference is in how rich text is provided to external clients, e.g., those using {JSON:API}. Take a look at the ProseMirror {JSON:API} example below to see what it looks like for consumers and frontend developers.
ProseMirror provides a parser for CKEditor-created content out of the box. Simply switching from a CKEditor-based text format to a ProseMirror-based text format will translate your existing HTML-structured content to the ProseMirror-based rich text structure (stored as JSON).
You can also use both CKEditor and ProseMirror in the same Drupal site.
Requirements
ProseMirror does not have requirements for other modules.
Installation
After adding the module to your site, install it using drush or the Drupal Extend UI. Please consider installing the prosemirror_defaults submodule as well if you're new to ProseMirror.
After configuring what elements and marks are available, either create a new text format or update an existing text format to use the ProseMirror editor instead of the CKEditor.
For more detailed configuration instructions, see README.md.
ProseMirror {JSON:API} Example
The code below is using the prosemirror_api_field submodule that adds a virtual field for text fields with an optimized data structure.
{
"data": {
"type": "node--article",
"id": "123e4567-e89b-12d3-a456-426614174000",
"attributes": {
"body_prosemirror": {
"processed": "<div class=\"ProseMirror-rendered\"><p>Hello <a href=\"/node/1\">world</a></p></div>",
"value": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello "
},
{
"type": "text",
"text": "world",
"marks": [
{
"type": "link",
"attrs": {
"linkType": "internal",
"entityType": "node",
"entityUuid": "550e8400-e29b-41d4-a716-446655440000",
"href": "entity:node/550e8400-e29b-41d4-a716-446655440000"
}
}
]
}
]
}
]
},
"included": [
{
"type": "node--page",
"id": "550e8400-e29b-41d4-a716-446655440000",
"meta": {
"drupal_internal__target_id": 1,
"label": "Referenced Node Title"
}
}
]
}
}
}
}
- Use the "processed" property the same way you would use it from the "body" field directly.
- Use the "value" property to customize the render logic.
- Use the "included" property to easily dereference and process links to other content, blocks, or embedded media items.
Advanced use cases
While you can limit ProseMirror to only standard formatting options (and we recommend that for most headless use cases to avoid layout cluttering), you can also allow editors to create nested content structures by including things like info boxes, accordions, or even columns. For example:
Extending ProseMirror
Creating custom elements and marks can all be done through configuration. For a higher degree of customization by code, you can create plugins. Plugins can extend both the PHP and JavaScript functionality. Check out the prosemirror_fontawesome_icons module for an example.
Maintainers
The ProseMirror is sponsored and maintained by Content Sync.
While ProseMirror is the recommended editor for working with Content Sync's Content Cloud, the ProseMirror module is fully open source, has no usage restrictions, and works completely independently of any commercial services.
If you would like to contribute, please create an issue in the Issue Queue on drupal.org. As a Content Sync customer, please create a ticket in the Content Sync helpdesk to receive SLA coverage.