ProseMirror Trailing Node Plugin
prosemirror-trailing-node is a plugin for the ProseMirror rich text editor that ensures there's always an editable node at the end of the document. This is particularly useful for preventing users from getting stuck within non-editable or complex nodes, allowing for continuous input. It automatically appends a configurable default node, such as a paragraph, when the last node in the document is not empty. The current stable version is 3.0.0, aligning with the major version 3 of the Remirror ecosystem, of which it is a part. Remirror, and by extension its associated plugins like this one, maintains an active release cadence with frequent patch updates to address issues and align with ProseMirror core updates, as seen in recent changelogs. Its key differentiator is its simple, focused solution for a common ProseMirror UX problem, integrated within a broader, actively developed framework.
Common errors
-
TypeError: trailingNode is not a function
cause Attempting to use CommonJS `require()` syntax with an ESM-only package or incorrect named import.fixEnsure you are using `import { trailingNode } from 'prosemirror-trailing-node';` in an ESM context. If using TypeScript, ensure your `tsconfig.json` targets `es2015` or higher and `moduleResolution` is set appropriately (e.g., `bundler`). -
Error: Cannot find module 'prosemirror-trailing-node'
cause The package or its peer dependencies are not installed correctly or not accessible in the current environment.fixRun `npm install prosemirror-trailing-node prosemirror-model prosemirror-state prosemirror-view` (or `yarn add`/`pnpm add`) to ensure all necessary packages are present. -
Error: (plugin prosemirror-trailing-node): 'nodeName' (or 'createNode') is required
cause The `nodeName` or `createNode` option was not provided to the `trailingNode` plugin configuration.fixWhen initializing the plugin, provide either `nodeName` (a string matching a schema node) or a `createNode` function: `trailingNode({ nodeName: 'paragraph' })`.
Warnings
- breaking Version 3.0.0 introduces breaking changes, primarily aligning with Remirror v3's move towards ESM-only imports and updated ProseMirror peer dependencies. Ensure your project is configured for ESM and that you update your core ProseMirror packages to compatible versions.
- gotcha This package requires specific peer dependencies of `prosemirror-model`, `prosemirror-state`, and `prosemirror-view`. Failure to install these or using incompatible versions can lead to runtime errors or unexpected behavior within your ProseMirror editor.
- gotcha The `nodeName` option in `trailingNode` must correspond to a valid node name defined in your ProseMirror schema. If the specified `nodeName` does not exist in the schema, the plugin may not function correctly or could throw errors.
Install
-
npm install prosemirror-trailing-node -
yarn add prosemirror-trailing-node -
pnpm add prosemirror-trailing-node
Imports
- trailingNode
const { trailingNode } = require('prosemirror-trailing-node');import { trailingNode } from 'prosemirror-trailing-node'; - TrailingNodeOptions
import type { TrailingNodeOptions } from 'prosemirror-trailing-node'; - EditorState
import EditorState from 'prosemirror-state';
import { EditorState } from 'prosemirror-state';
Quickstart
import { schema } from 'prosemirror-schema-basic';
import { EditorState } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
import { trailingNode } from 'prosemirror-trailing-node';
const editorSchema = schema;
// Initialize the editor state with the trailingNode plugin.
const state = EditorState.create({
schema: editorSchema,
plugins: [
trailingNode({
ignoredNodes: ['code_block'], // Example: don't add trailing node after code blocks
nodeName: 'paragraph' // The node type to append
})
]
});
// Create the editor view and mount it to the DOM.
const view = new EditorView(document.body, {
state,
dispatchTransaction(transaction) {
const newState = view.state.apply(transaction);
view.updateState(newState);
}
});
console.log('ProseMirror editor with trailing node plugin initialized.');