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

# DraftJS 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>
> ```

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

```bash theme={null}
npm i @veltdev/draftjs-velt-comments draft-js
```

#### Step 3: Configure the DraftJS editor with the Velt Comments extension

Use `DraftJSVeltEditor` instead of the standard DraftJS `Editor`. This wrapper component handles the DraftJS decorator setup, content change detection, and annotation tracking.

> [tab] React / Next.js
>
> ```js theme={null}
> import { useState } from 'react';
> import { EditorState } from 'draft-js';
> import { DraftJSVeltEditor } from '@veltdev/draftjs-velt-comments';
>
> function DraftJSEditor() {
>   const [editorState, setEditorState] = useState(() =>
>     EditorState.createEmpty()
>   );
>
>   return (
>     <DraftJSVeltEditor
>       editorState={editorState}
>       onChange={setEditorState}
>       placeholder="Start typing..."
>     />
>   );
> }
> ```

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

* Add a button that users can click after selecting text in the DraftJS editor.
* Use `onMouseDown` with `preventDefault()` so the browser does not move focus away from the editor and clear the current text selection.

> [tab] React / Next.js
>
> ```js theme={null}
> import { useCallback, useEffect, useRef, useState } from 'react';
> import { EditorState } from 'draft-js';
> import {
>   DraftJSVeltEditor,
>   addComment,
> } from '@veltdev/draftjs-velt-comments';
>
> function DraftJSEditor() {
>   const [editorState, setEditorState] = useState(() =>
>     EditorState.createEmpty()
>   );
>
>   const editorRef = useRef({ editorState, setEditorState });
>
>   useEffect(() => {
>     editorRef.current = { editorState, setEditorState };
>   }, [editorState]);
>
>   const handleAddComment = useCallback(() => {
>     addComment({ editor: editorRef.current });
>   }, []);
>
>   return (
>     <div>
>       <button
>         onMouseDown={(event) => event.preventDefault()}
>         onClick={handleAddComment}
>       >
>         Add Comment
>       </button>
>
>       <DraftJSVeltEditor
>         editorState={editorState}
>         onChange={setEditorState}
>         placeholder="Start typing..."
>       />
>     </div>
>   );
> }
> ```

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

* Call this method to add a comment to selected text in the DraftJS editor.
* Params: [`AddCommentRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#addcommentrequest-7)
  * `editor`: DraftJS editor wrapper object with `{ editorState, setEditorState }`.
  * `editorId`: Id of the editor. Use this if you have multiple DraftJS 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
>
> ```js theme={null}
> import { addComment } from '@veltdev/draftjs-velt-comments';
>
> const addCommentRequest = {
>   editor,
>   editorId: 'EDITOR_ID',
>   context: {
>     storyId: 'story-id',
>     storyName: 'story-name',
>   },
> };
>
> addComment(addCommentRequest);
> ```

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

* Get comment data from Velt SDK and render it in the DraftJS editor.
* Params: [`RenderCommentsRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#rendercommentsrequest-7)
  * `editor`: DraftJS editor wrapper object with `{ editorState, setEditorState }`.
  * `editorId`: Id of the editor. Use this if you have multiple DraftJS editors on the same page. (optional)
  * `commentAnnotations`: Array of Comment Annotation objects.

> [tab] React / Next.js
>
> ```js theme={null}
> import { useEffect, useRef, useState } from 'react';
> import { EditorState } from 'draft-js';
> import { useCommentAnnotations } from '@veltdev/react';
> import {
>   DraftJSVeltEditor,
>   renderComments,
> } from '@veltdev/draftjs-velt-comments';
>
> function DraftJSEditor() {
>   const annotations = useCommentAnnotations();
>   const [editorState, setEditorState] = useState(() =>
>     EditorState.createEmpty()
>   );
>
>   const editorRef = useRef({ editorState, setEditorState });
>
>   useEffect(() => {
>     editorRef.current = { editorState, setEditorState };
>   }, [editorState]);
>
>   useEffect(() => {
>     renderComments({
>       editor: editorRef.current,
>       editorId: 'EDITOR_ID',
>       commentAnnotations: annotations ?? [],
>     });
>   }, [annotations]);
>
>   return (
>     <DraftJSVeltEditor
>       editorState={editorState}
>       onChange={setEditorState}
>     />
>   );
> }
> ```

#### Step 7: Persist DraftJS content without Velt comment entities (optional)

* When saving editor content to your backend, remove Velt comment entities to keep your stored content clean.
* Use `exportContentStateWithoutComments` before converting DraftJS content to raw JSON.

```js theme={null}
import { convertToRaw } from 'draft-js';
import { exportContentStateWithoutComments } from '@veltdev/draftjs-velt-comments';

const cleanContent = exportContentStateWithoutComments(
  editorState.getCurrentContent()
);

const rawContent = convertToRaw(cleanContent);
```

#### Step 8: Style the commented text

* Style the commented text by adding CSS for the `velt-comment-text` element.

```css theme={null}
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

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

## APIs

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

A wrapper around the DraftJS `Editor` component that automatically handles decorator setup, content change detection, and Velt annotation context updates.

* Props: [`DraftJSVeltEditorProps`](https://velt.dev/docs/api-reference/sdk/models/data-models#draftjsvelteditorprops)
  * `editorState`: Current DraftJS editor state.
  * `onChange`: Callback when the editor state changes.
  * `editorId`: Optional editor ID for multi-editor scenarios.
  * All other standard DraftJS `Editor` props are forwarded.

> [tab] React / Next.js
>
> ```jsx theme={null}
> import { DraftJSVeltEditor } from '@veltdev/draftjs-velt-comments';
>
> <DraftJSVeltEditor
>   editorState={editorState}
>   onChange={setEditorState}
>   editorId="my-editor"
>   placeholder="Start typing..."
> />
> ```

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

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.md#addcommentrequest-7)`) => Promise<void>`
* Params: `request:` [AddCommentRequest](https://velt.dev/docs/api-reference/sdk/models/data-models.md#addcommentrequest-7)
* Returns: `Promise<void>`

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

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

Renders and highlights comment annotations in the DraftJS editor.

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

> [tab] React / Next.js
>
> ```jsx theme={null}
> import { renderComments } from '@veltdev/draftjs-velt-comments';
>
> useEffect(() => {
>   renderComments({
>     editor: editorRef.current,
>     editorId: 'my-editor',
>     commentAnnotations,
>   });
> }, [commentAnnotations]);
> ```

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

Returns a DraftJS `ContentState` without Velt comment entities. Use it before saving content outside Velt.

> [tab] React / Next.js
>
> ```jsx theme={null}
> import { convertToRaw } from 'draft-js';
> import { exportContentStateWithoutComments } from '@veltdev/draftjs-velt-comments';
>
> const cleanContent = exportContentStateWithoutComments(
>   editorState.getCurrentContent()
> );
> const rawContent = convertToRaw(cleanContent);
> ```


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