Documentation Index
Fetch the complete documentation index at: https://docs.velt.dev/llms.txt
Use this file to discover all available pages before exploring further.
Setup
- Add the
Velt Comments component to the root of your app.
- This component is required to render comments in your app.
- Set the
text mode prop to false to hide the default text comment tool.
React / Next.js
Other Frameworks
<VeltProvider apiKey="API_KEY">
<VeltComments textMode={false} />
</VeltProvider>
<body>
<velt-comments text-mode="false"></velt-comments>
</body>
Step 2: Install the Velt Lexical extension
npm install @veltdev/lexical-velt-comments @veltdev/client lexical
- Register the
CommentNode and configure your Lexical editor.
React / Next.js
Other Frameworks
import { LexicalComposer } from '@lexical/react/LexicalComposer';
import { CommentNode } from '@veltdev/lexical-velt-comments';
const initialConfig = {
namespace: 'MyEditor',
nodes: [CommentNode],
onError: (error) => console.error(error),
};
function App() {
return (
<LexicalComposer initialConfig={initialConfig}>
{/* Editor plugins */}
</LexicalComposer>
);
}
import { createEditor } from 'lexical';
import { registerRichText } from '@lexical/rich-text';
import { CommentNode, addComment, renderComments } from '@veltdev/lexical-velt-comments';
const editor = createEditor({
namespace: 'MyEditor',
nodes: [CommentNode],
onError: (error) => {
throw error;
},
});
// Set the root element
editor.setRootElement(document.querySelector('#editor'));
// Register rich text support
registerRichText(editor);
- Add a button that users can click to add comments after selecting text.
React / Next.js
Other Frameworks
import { useCallback } from 'react';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { addComment } from '@veltdev/lexical-velt-comments';
function AddCommentPlugin() {
const [editor] = useLexicalComposerContext();
const handleAddComment = useCallback(() => {
addComment({ editor });
}, [editor]);
return (
<button onClick={handleAddComment}>
Add Comment
</button>
);
}
<button id="add-comment-btn">Add Comment</button>
<div id="editor" contenteditable="true"></div>
import { addComment } from '@veltdev/lexical-velt-comments';
const addCommentBtn = document.getElementById('add-comment-btn');
addCommentBtn.addEventListener('click', () => {
addComment({ editor });
});
- Call this method to add a comment to selected text in the Lexical editor. You can use this when the user clicks on a comment button or presses a keyboard shortcut.
- Params:
AddCommentRequest. It has the following properties:
editor: Instance of the Lexical Editor.
editorId: Id of the editor. Use this if you have multiple Lexical editors on the same page. (optional)
context: Add any custom metadata to the Comment Annotation. Learn more. (optional)
React / Next.js
Other Frameworks
import { addComment } from '@veltdev/lexical-velt-comments';
const addCommentRequest = {
editor,
editorId: 'EDITOR_ID',
context: {
storyId: 'story-id',
storyName: 'story-name',
},
};
addComment(addCommentRequest);
import { addComment } from '@veltdev/lexical-velt-comments';
const addCommentRequest = {
editor,
editorId: 'EDITOR_ID',
context: {
storyId: 'story-id',
storyName: 'story-name',
},
};
addComment(addCommentRequest);
- Get the comment data from Velt SDK and render it in the Lexical Editor.
- Params:
RenderCommentsRequest. It has the following properties:
editor: Instance of the Lexical Editor.
editorId: Id of the editor. Use this if you have multiple Lexical editors on the same page. (optional)
commentAnnotations: Array of Comment Annotation objects.
React / Next.js
Other Frameworks
import { renderComments } from '@veltdev/lexical-velt-comments';
import { useCommentAnnotations } from '@veltdev/react';
const annotations = useCommentAnnotations();
useEffect(() => {
if (editor && annotations) {
renderComments({
editor,
editorId: 'EDITOR_ID',
commentAnnotations: annotations,
});
}
}, [editor, annotations]);
import { renderComments } from '@veltdev/lexical-velt-comments';
const commentElement = Velt.getCommentElement();
commentElement.getAllCommentAnnotations().subscribe((annotations) => {
if (editor && annotations?.length) {
const renderCommentsRequest = {
editor,
editorId: 'EDITOR_ID',
commentAnnotations: annotations,
};
renderComments(renderCommentsRequest);
}
});
Step 7: Persist Editor Content Without Velt Marks (optional)
- When saving editor content to your backend, you may want to exclude Velt comment marks to keep the content clean.
- Use
exportJSONWithoutComments to export the editor state as JSON without Velt comment nodes.
import { exportJSONWithoutComments } from '@veltdev/lexical-velt-comments';
// Get clean editor state JSON without Velt comment marks
const cleanState = exportJSONWithoutComments(editor);
// Save to your backend
localStorage.setItem('editor-content', JSON.stringify(cleanState));
- Style the commented text by adding CSS for the
velt-comment-text element.
velt-comment-text {
background-color: rgba(255, 255, 0, 0.3);
border-bottom: 2px solid #ffcc00;
cursor: pointer;
}
velt-comment-text:hover {
background-color: rgba(255, 255, 0, 0.5);
}
velt-comment-text.velt-comment-selected {
background-color: rgba(255, 255, 0, 0.5);
}
Complete Example
APIs
A custom Lexical node used to wrap commented text with comment annotation metadata.
- Usage: Register the node with your Lexical editor so comment elements render correctly.
React / Next.js
Other Frameworks
import { LexicalComposer } from '@lexical/react/LexicalComposer';
import { CommentNode } from '@veltdev/lexical-velt-comments';
const initialConfig = {
namespace: 'MyEditor',
nodes: [CommentNode],
onError: console.error,
};
export default function Editor() {
return <LexicalComposer initialConfig={initialConfig}>{/* plugins */}</LexicalComposer>;
}
import { createEditor } from 'lexical';
import { CommentNode } from '@veltdev/lexical-velt-comments';
const editor = createEditor({
namespace: 'MyEditor',
nodes: [CommentNode],
onError: (error) => {
throw error;
},
});
Creates a comment annotation for the currently selected text in the editor.
- Params:
- Returns:
Promise<void>
React / Next.js
Other Frameworks
import { addComment } from '@veltdev/lexical-velt-comments';
<button onClick={() => addComment({ editor, editorId: 'my-editor' })}>
Comment
</button>
import { addComment } from '@veltdev/lexical-velt-comments';
addComment({
editor,
editorId: 'my-editor',
context: { customData: 'value' },
});
Renders and highlights comment annotations in the editor.
React / Next.js
Other Frameworks
import { useEffect } from 'react';
import { renderComments } from '@veltdev/lexical-velt-comments';
import { useCommentAnnotations } from '@veltdev/react';
const annotations = useCommentAnnotations();
useEffect(() => {
if (editor && annotations) {
renderComments({
editor,
editorId: 'my-editor',
commentAnnotations: annotations,
});
}
}, [editor, annotations]);
import { renderComments } from '@veltdev/lexical-velt-comments';
const commentElement = Velt.getCommentElement();
commentElement.getAllCommentAnnotations().subscribe((annotations) => {
if (editor && annotations) {
renderComments({
editor,
editorId: 'my-editor',
commentAnnotations: annotations,
});
}
});
Exports the editor state as serialized JSON while stripping out all comment nodes and normalizing adjacent text nodes.
- Params:
editor: LexicalEditor
- Returns:
SerializedEditorState
import { exportJSONWithoutComments } from '@veltdev/lexical-velt-comments';
const cleanState = exportJSONWithoutComments(editor);