> ## Documentation Index
> Fetch the complete documentation index at: https://velt.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ProseMirror Setup

![](https://mintcdn.com/velt/gAz_vLsG-ukKamYM/gifs/Add-Text-Comments.gif?s=1da499b73486c2acd4667b517baab389)

## Setup

#### Step 1: Add Comment components

* 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.

> [tab] React / Next.js
>
> ```js theme={null}
> <VeltProvider apiKey="API_KEY">
>   <VeltComments textMode={false} />
> </VeltProvider>
> ```

> [tab] Other Frameworks
>
> ```html theme={null}
> <body>
>   <velt-comments text-mode="false"></velt-comments>
> </body>
> ```

#### Step 2: Install the Velt ProseMirror extension

```bash theme={null}
npm i @veltdev/prosemirror-velt-comments prosemirror-model prosemirror-state prosemirror-view
```

For the examples below, also install the standard ProseMirror example packages:

```bash theme={null}
npm i prosemirror-schema-basic prosemirror-example-setup
```

#### Step 3: Configure the ProseMirror editor with the Velt Comments plugin

Add `VeltCommentsPlugin` to the `plugins` array when creating your `EditorState`.

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { useEffect, useRef } from 'react';
> import { schema } from 'prosemirror-schema-basic';
> import { exampleSetup } from 'prosemirror-example-setup';
> import { EditorState } from 'prosemirror-state';
> import { EditorView } from 'prosemirror-view';
> import { VeltCommentsPlugin } from '@veltdev/prosemirror-velt-comments';
>
> const EDITOR_ID = 'my-editor';
>
> function ProseMirrorEditor() {
>   const containerRef = useRef(null);
>   const viewRef = useRef(null);
>
>   useEffect(() => {
>     if (!containerRef.current) return;
>
>     const state = EditorState.create({
>       schema,
>       plugins: [
>         ...exampleSetup({ schema }),
>         VeltCommentsPlugin({ editorId: EDITOR_ID }),
>       ],
>     });
>
>     const view = new EditorView(containerRef.current, { state });
>     viewRef.current = view;
>
>     return () => {
>       view.destroy();
>       viewRef.current = null;
>     };
>   }, []);
>
>   return <div ref={containerRef} />;
> }
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> import { schema } from 'prosemirror-schema-basic';
> import { exampleSetup } from 'prosemirror-example-setup';
> import { EditorState } from 'prosemirror-state';
> import { EditorView } from 'prosemirror-view';
> import { VeltCommentsPlugin } from '@veltdev/prosemirror-velt-comments';
>
> const state = EditorState.create({
>   schema,
>   plugins: [
>     ...exampleSetup({ schema }),
>     VeltCommentsPlugin({ editorId: 'my-editor' }),
>   ],
> });
>
> const view = new EditorView(document.querySelector('#editor'), { state });
> ```

#### Step 4: Add a comment button to your ProseMirror editor

Add a button that users can click to add comments after selecting text in the ProseMirror editor.

**Important:** Use `onMouseDown` with `preventDefault()` so the browser does not move focus away from the editor before `addComment` reads the current selection.

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { addComment } from '@veltdev/prosemirror-velt-comments';
>
> const handleAddComment = () => {
>   if (!viewRef.current) return;
>
>   addComment({
>     editor: viewRef.current,
>     editorId: EDITOR_ID,
>   });
> };
>
> <button
>   onMouseDown={(event) => event.preventDefault()}
>   onClick={handleAddComment}
> >
>   Add Comment
> </button>
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> import { addComment } from '@veltdev/prosemirror-velt-comments';
>
> const addCommentButton = document.querySelector('#add-comment');
>
> addCommentButton.addEventListener('mousedown', (event) => {
>   event.preventDefault();
> });
>
> addCommentButton.addEventListener('click', () => {
>   addComment({ editor: view, editorId: 'my-editor' });
> });
> ```

#### Step 5: Call `addComment` to add a comment

* Call this method to add a comment to selected text in the ProseMirror editor.
* Params: [`AddCommentRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#addcommentrequest-8). It has the following properties:
  * `editor`: ProseMirror `EditorView`.
  * `editorId`: Id of the editor. Use this if you have multiple ProseMirror editors on the same page. (optional)
  * `context`: Add custom metadata to the Comment Annotation. [Learn more](https://velt.dev/docs/async-collaboration/comments/customize-behavior.md#metadata). (optional)

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { addComment } from '@veltdev/prosemirror-velt-comments';
>
> const addCommentRequest = {
>   editor: viewRef.current,
>   editorId: 'EDITOR_ID',
>   context: {
>     storyId: 'story-id',
>     storyName: 'story-name',
>   },
> };
>
> addComment(addCommentRequest);
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> import { addComment } from '@veltdev/prosemirror-velt-comments';
>
> const addCommentRequest = {
>   editor: view,
>   editorId: 'EDITOR_ID',
>   context: {
>     storyId: 'story-id',
>     storyName: 'story-name',
>   },
> };
>
> addComment(addCommentRequest);
> ```

#### Step 6: Render comments in ProseMirror editor

* Get the comment data from Velt SDK and render it in the ProseMirror editor.
* Params: [`RenderCommentsRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#rendercommentsrequest-8). It has the following properties:
  * `editor`: ProseMirror `EditorView`.
  * `editorId`: Id of the editor. Use this if you have multiple ProseMirror editors on the same page. (optional)
  * `commentAnnotations`: Array of Comment Annotation objects.

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { useEffect } from 'react';
> import { useCommentAnnotations } from '@veltdev/react';
> import { renderComments } from '@veltdev/prosemirror-velt-comments';
>
> const commentAnnotations = useCommentAnnotations();
>
> useEffect(() => {
>   if (!viewRef.current) return;
>
>   renderComments({
>     editor: viewRef.current,
>     editorId: 'EDITOR_ID',
>     commentAnnotations: commentAnnotations ?? [],
>   });
> }, [commentAnnotations]);
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> import { renderComments } from '@veltdev/prosemirror-velt-comments';
>
> const commentElement = Velt.getCommentElement();
> commentElement.getAllCommentAnnotations().subscribe((annotations) => {
>   renderComments({
>     editor: view,
>     editorId: 'EDITOR_ID',
>     commentAnnotations: annotations,
>   });
> });
> ```

#### Step 7: Re-apply ProseMirror comment highlights (optional)

* ProseMirror renders comment highlights as view-only overlay elements.
* The integration does not write Velt comment marks into your ProseMirror schema or saved document.
* Save your ProseMirror document normally. After you recreate the `EditorView` or replace document content, call `renderComments` again.

```ts theme={null}
const json = view.state.doc.toJSON();
// Save json to your backend.

renderComments({
  editor: view,
  editorId: 'EDITOR_ID',
  commentAnnotations,
});
```

#### Step 8: Style the commented text

* You can style the commented text by adding CSS for the `velt-comment-text` element.
* Use the `comment-available` attribute to apply styles only after comment data has loaded.

```css theme={null}
velt-comment-text[comment-available="true"] {
  background-color: rgba(255, 255, 0, 0.3);
  border-bottom: 2px solid #ffcc00;
  cursor: pointer;
}

velt-comment-text[comment-available="true"]: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

[https://sample-apps-prosemirror-comments-demo.vercel.app/](https://sample-apps-prosemirror-comments-demo.vercel.app/)

## APIs

#### [VeltCommentsPlugin()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#veltcommentsplugin)

Creates the ProseMirror plugin that powers Velt comments. Add it to your editor state's `plugins` array.

* Params: `config?:` [`VeltCommentsPluginConfig`](https://velt.dev/docs/api-reference/sdk/models/data-models#veltcommentspluginconfig-1)
* Returns: ProseMirror `Plugin`

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { schema } from 'prosemirror-schema-basic';
> import { exampleSetup } from 'prosemirror-example-setup';
> import { EditorState } from 'prosemirror-state';
> import { VeltCommentsPlugin } from '@veltdev/prosemirror-velt-comments';
>
> const state = EditorState.create({
>   schema,
>   plugins: [
>     ...exampleSetup({ schema }),
>     VeltCommentsPlugin({ editorId: 'my-editor' }),
>   ],
> });
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> import { VeltCommentsPlugin } from '@veltdev/prosemirror-velt-comments';
>
> VeltCommentsPlugin({ editorId: 'my-editor' });
> ```

#### [addComment()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#addcomment-9)

Creates a comment annotation for the currently selected text in the editor.

* Signature: `async (request:` [`AddCommentRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#addcommentrequest-8)`) => Promise<void>`
* Params: `request:` [`AddCommentRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#addcommentrequest-8)
* Returns: `Promise<void>`

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { addComment } from '@veltdev/prosemirror-velt-comments';
>
> const handleAddComment = () => {
>   if (!viewRef.current) return;
>   addComment({ editor: viewRef.current, editorId: 'my-editor' });
> };
>
> <button
>   onMouseDown={(event) => event.preventDefault()}
>   onClick={handleAddComment}
> >
>   Comment
> </button>
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> import { addComment } from '@veltdev/prosemirror-velt-comments';
>
> addComment({
>   editor: view,
>   editorId: 'my-editor',
>   context: { customData: 'value' },
> });
> ```

#### [renderComments()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#rendercomments-9)

Renders and highlights comment annotations in the ProseMirror editor.

* Signature: `(request:` [`RenderCommentsRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#rendercommentsrequest-8)`) => void`
* Params: `request:` [`RenderCommentsRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#rendercommentsrequest-8)
* Returns: `void`

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { useEffect } from 'react';
> import { useCommentAnnotations } from '@veltdev/react';
> import { renderComments } from '@veltdev/prosemirror-velt-comments';
>
> const annotations = useCommentAnnotations();
>
> useEffect(() => {
>   if (!viewRef.current) return;
>
>   renderComments({
>     editor: viewRef.current,
>     editorId: 'my-editor',
>     commentAnnotations: annotations ?? [],
>   });
> }, [annotations]);
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> import { renderComments } from '@veltdev/prosemirror-velt-comments';
>
> const commentElement = Velt.getCommentElement();
> commentElement.getAllCommentAnnotations().subscribe((annotations) => {
>   renderComments({
>     editor: view,
>     editorId: 'my-editor',
>     commentAnnotations: annotations,
>   });
> });
> ```

#### [veltCommentsPluginKey](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#veltcommentspluginkey)

The ProseMirror `PluginKey` used by the package. Use it only for advanced inspection of plugin state.

* Params: none
* Returns: `PluginKey`

```ts theme={null}
import { veltCommentsPluginKey } from '@veltdev/prosemirror-velt-comments';

const state = veltCommentsPluginKey.getState(view.state);
const anchors = state?.anchors;
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.