Add Velt text comments to a TinyMCE editor with view-only overlay highlights that preserve your TinyMCE content, schema, undo history, and saved HTML.
The TinyMCE integration renders comment highlights as view-only overlay elements positioned over the commented text. It does not modify your TinyMCE content, schema, undo history, or saved HTML.
npm i @veltdev/tinymce-velt-comments @tinymce/tinymce-react tinymce
npm i @veltdev/tinymce-velt-comments @veltdev/client tinymce
tinymce is a peer dependency and must be provided by your TinyMCE app. Import the self-hosted TinyMCE assets used by your editor so @tinymce/tinymce-react and the Velt plugin use the same TinyMCE instance.
Step 3: Configure the TinyMCE editor with the Velt Comments plugin
Add VeltCommentsPlugin to the TinyMCE plugins list and set velt_comments_editor_id in the editor init options. Capture the TinyMCE editor instance from onInit or the init event, then render Velt comment annotations into the editor with renderComments.
React / Next.js
Other Frameworks
import { useEffect, useState } from 'react';import { Editor as TinyMCEReact } from '@tinymce/tinymce-react';import { useCommentAnnotations } from '@veltdev/react';import type { Editor as TinyMCEEditor } from 'tinymce';import { VeltCommentsPlugin, renderComments } from '@veltdev/tinymce-velt-comments';import 'tinymce';import 'tinymce/icons/default';import 'tinymce/themes/silver';import 'tinymce/models/dom';import 'tinymce/plugins/lists';import 'tinymce/plugins/link';import 'tinymce/skins/ui/oxide/skin.min.css';import contentUiCss from 'tinymce/skins/ui/oxide/content.min.css?raw';import contentCss from 'tinymce/skins/content/default/content.min.css?raw';const EDITOR_ID = 'my-editor';function TinyMCEEditor() { const [editor, setEditor] = useState<TinyMCEEditor | null>(null); const annotations = useCommentAnnotations(); useEffect(() => { if (!editor) return; renderComments({ editor, editorId: EDITOR_ID, commentAnnotations: annotations ?? [], }); }, [editor, annotations]); return ( <TinyMCEReact licenseKey="gpl" initialValue="<p>Select text, then add a comment.</p>" init={{ license_key: 'gpl', skin: false, content_css: false, content_style: `${contentUiCss}\n${contentCss}`, plugins: ['lists', 'link', VeltCommentsPlugin], toolbar: 'undo redo | bold italic | bullist numlist | link | addveltcomment', velt_comments_editor_id: EDITOR_ID, }} onInit={(_event, nextEditor) => setEditor(nextEditor)} /> );}
The package registers a TinyMCE plugin named veltcomments. You can pass the exported VeltCommentsPlugin constant in plugins, or use the string 'veltcomments' after the package has been imported. It also registers a TinyMCE toolbar button named addveltcomment.
Step 4: Add a comment button to your TinyMCE editor
Add a button that users can click to add comments after selecting text in the TinyMCE editor.Important: Use onMouseDown with preventDefault() so the browser does not move focus away from the editor before addComment reads the current selection. Keep the actual addComment call in onClick.
The library automatically writes context.textEditorConfig with the selected text, its 1-based occurrence index in the document, and the editor ID when one is provided. If the editor is inside an element with data-velt-location-id, that value is sent to Velt as the annotation location.
renderComments filters annotations by context.textEditorConfig.editorId. Resolved comments with status.type === 'terminal' are hidden unless they are currently selected in Velt.
You can style the commented text by adding CSS for the velt-comment-text element.
TinyMCE highlights are overlay elements in the outer document, not inside the editor iframe, so add this CSS to your page stylesheet instead of content_style.
For a vanilla TinyMCE app, initialize Velt with @veltdev/client, add the Velt comments web component to the page, and subscribe to annotations through the Velt comment element.
When using multiple editors on the same page, provide a unique editorId to TinyMCE’s velt_comments_editor_id init option, addComment, and renderComments.
The package includes TypeScript definitions. Key type exports:
import type { AddCommentRequest, RenderCommentsRequest, TinymceVeltCommentsConfig, CommentAnnotationContext,} from '@veltdev/tinymce-velt-comments';import type { CommentAnnotation } from '@veltdev/types';
Runtime exports:
import { VeltCommentsPlugin, registerVeltCommentsPlugin, addComment, renderComments,} from '@veltdev/tinymce-velt-comments';
The registered TinyMCE plugin name ('veltcomments') that powers Velt comments. Importing the library registers it; add it to the TinyMCE editor’s plugins list.Init options:
velt_comments_editor_id?: string - Unique identifier for this editor instance.
velt_comments_persist_marks?: boolean - Reserved for API parity; highlights are always rendered as view-only overlays.
Explicitly registers the veltcomments plugin with a TinyMCE instance. Importing the package auto-registers the plugin when a TinyMCE instance is available; use this method when TinyMCE is loaded or provided later.Parameters:
instance?: TinyMCE - TinyMCE instance to register against.
Returns:void
import tinymce from 'tinymce';import { registerVeltCommentsPlugin } from '@veltdev/tinymce-velt-comments';registerVeltCommentsPlugin(tinymce);