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

# Quill 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 Quill extension

```bash theme={null}
npm i @veltdev/quill-velt-comments
```

#### Step 3: Configure the Quill editor with the Velt Comments module

> [tab] React / Next.js
>
> ```js theme={null}
> import { useEffect, useRef, useState } from 'react';
> import Quill from 'quill';
> import { QuillVeltComments } from '@veltdev/quill-velt-comments';
>
> // Register the module with Quill (once, outside component)
> Quill.register('modules/veltComments', QuillVeltComments);
>
> function QuillEditor() {
>   const editorRef = useRef(null);
>   const [quill, setQuill] = useState(null);
>
>   useEffect(() => {
>     if (!editorRef.current) return;
>
>     const quillInstance = new Quill(editorRef.current, {
>       theme: 'snow',
>       modules: {
>         veltComments: {
>           persistVeltMarks: true,
>         },
>       },
>     });
>
>     setQuill(quillInstance);
>   }, []);
>
>   return <div ref={editorRef} />;
> }
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> import Quill from 'quill';
> import { QuillVeltComments } from '@veltdev/quill-velt-comments';
>
> // Register the module with Quill
> Quill.register('modules/veltComments', QuillVeltComments);
>
> // Create editor with the module enabled
> const quill = new Quill('#editor', {
>   theme: 'snow',
>   modules: {
>     veltComments: {
>       persistVeltMarks: true,
>     },
>   },
> });
> ```

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

Add a button that users can click to add comments after selecting text.

> [!WARNING]
>
> When clicking a button, the browser moves focus to the button which clears the editor selection. You must save the selection on `mousedown` (before focus changes) and restore it before adding the comment.

> [tab] React / Next.js
>
> ```js theme={null}
> import { useCallback, useRef } from 'react';
> import { addComment } from '@veltdev/quill-velt-comments';
>
> // Inside your QuillEditor component from Step 3:
> const savedSelectionRef = useRef(null);
>
> const handleAddComment = useCallback(() => {
>   if (quill) {
>     if (savedSelectionRef.current) {
>       quill.setSelection(savedSelectionRef.current.index, savedSelectionRef.current.length);
>     }
>     addComment({ editor: quill });
>     savedSelectionRef.current = null;
>   }
> }, [quill]);
>
> // In your JSX:
> <button
>   onMouseDown={(e) => {
>     e.preventDefault();
>     const sel = quill?.getSelection();
>     if (sel?.length > 0) savedSelectionRef.current = sel;
>   }}
>   onClick={handleAddComment}
> >
>   Add Comment
> </button>
> ```

> [tab] Other Frameworks
>
> ```html theme={null}
> <button id="add-comment-btn">Add Comment</button>
> <div id="editor"></div>
> ```
>
> ```js theme={null}
> import { addComment } from '@veltdev/quill-velt-comments';
>
> let savedSelection = null;
> const btn = document.getElementById('add-comment-btn');
>
> btn.addEventListener('mousedown', () => {
>   const sel = quill.getSelection();
>   if (sel && sel.length > 0) savedSelection = sel;
> });
>
> btn.addEventListener('click', () => {
>   if (savedSelection) quill.setSelection(savedSelection.index, savedSelection.length);
>   addComment({ editor: quill });
>   savedSelection = null;
> });
> ```

> [!TIP]
>
> Unlike Tiptap, Quill does not have a built-in bubble menu. You will need to create your own comment button or toolbar item.

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

* Call this method to add a comment to selected text in the Quill editor. You can use this when the user clicks on the comment button or presses a keyboard shortcut.
* Params: [`AddCommentRequest`](https://velt.dev/docs/api-reference/sdk/models/data-models#addcommentrequest-6). It has the following properties:
  * `editor`: Instance of the Quill editor.
  * `editorId`: Id of the Quill editor. Use this if you have multiple Quill editors on the same page. (optional)
  * `context`: Add any 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/quill-velt-comments';
>
> const addCommentRequest = {
>   editor: quill,
>   editorId: 'EDITOR_ID',
>   context: {
>     storyId: 'story-id',
>     storyName: 'story-name',
>   },
> };
>
> addComment(addCommentRequest);
> ```

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

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

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

> [tab] React / Next.js
>
> ```js theme={null}
> import { renderComments } from '@veltdev/quill-velt-comments';
> import { useCommentAnnotations } from '@veltdev/react';
>
> const annotations = useCommentAnnotations();
>
> useEffect(() => {
>   if (quill && annotations?.length) {
>     const renderCommentsRequest = {
>       editor: quill,
>       editorId: 'EDITOR_ID',
>       commentAnnotations: annotations,
>     };
>     renderComments(renderCommentsRequest);
>   }
> }, [quill, annotations]);
> ```

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

#### Step 7: Persist Velt Comment Marks (optional)

* By default, Velt comment marks (`<velt-comment-text>`) are persisted by the Velt SDK. When the editor loads and the Velt SDK initializes, the marks will be automatically added to the editor.
* If you plan to store the contents of the Quill editor on your end with the comment marks already included, you can disable this feature.
* Default: `true`

```js theme={null}
const quill = new Quill(editorRef.current, {
  theme: 'snow',
  modules: {
    veltComments: {
      persistVeltMarks: false,
    },
  },
});
```

#### Step 8: Style the commented text

* You can 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);
}
```

## APIs

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

The Velt Comments module for Quill. Register it with Quill before creating the editor.

* Params: `options?:` [QuillVeltCommentsConfig](https://velt.dev/docs/api-reference/sdk/models/data-models.md#quillveltcommentsconfig)
  * `editorId?: string` - Unique identifier for this editor instance (for multi-editor scenarios)
  * `persistVeltMarks?: boolean` - Whether to persist Velt marks. Default: `true`
* Returns: `Quill Module`

> [tab] React / Next.js
>
> ```tsx theme={null}
> import Quill from 'quill';
> import { QuillVeltComments } from '@veltdev/quill-velt-comments';
>
> Quill.register('modules/veltComments', QuillVeltComments);
>
> const quillInstance = new Quill(editorRef.current, {
>   theme: 'snow',
>   modules: {
>     veltComments: {
>       editorId: 'my-editor',
>       persistVeltMarks: true,
>     },
>   },
> });
> ```

> [tab] Other Frameworks
>
> ```tsx theme={null}
> import Quill from 'quill';
> import { QuillVeltComments } from '@veltdev/quill-velt-comments';
>
> Quill.register('modules/veltComments', QuillVeltComments);
>
> const quill = new Quill('#editor', {
>   theme: 'snow',
>   modules: {
>     veltComments: {
>       editorId: 'my-editor',
>       persistVeltMarks: true,
>     },
>   },
> });
> ```

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

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

* Params:
  * `request:` [AddCommentRequest](https://velt.dev/docs/api-reference/sdk/models/data-models.md#addcommentrequest-6)
    * `editor: Quill`
    * `editorId?: string`
    * `context?: object`
* Returns: `Promise<void>`

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { addComment } from '@veltdev/quill-velt-comments';
>
> <button
>   onMouseDown={(e) => {
>     e.preventDefault();
>     addComment({
>       editor: quill,
>       editorId: 'my-editor',
>       context: { customData: 'value' }
>     });
>   }}
> >
>   Comment
> </button>
> ```

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

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

Renders and highlights comment annotations in the editor.

* Params:
  * `request:` [RenderCommentsRequest](https://velt.dev/docs/api-reference/sdk/models/data-models.md#rendercommentsrequest-6)
    * `editor: Quill`
    * `editorId?: string`
    * `commentAnnotations?:` [CommentAnnotation\[\]](https://velt.dev/docs/api-reference/sdk/models/data-models#commentannotation)
* Returns: `void`

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

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


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