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

# <Canvas> Comments

> Add comments to an HTML Canvas.

<Tabs>
  <Tab title="React / Next.js">
    <Steps titleSize="h2">
      <Step title="Import the VeltCommentPin component and the useCommentAnnotations() hook. ">
        Import the `VeltCommentPin` component and the `useCommentAnnotations()` hook.

        ```jsx theme={null}
        import { VeltCommentPin, useCommentAnnotations } from '@veltdev/react';
        ```
      </Step>

      <Step title="Add custom metadata when comment is added">
        Use the `onCommentAdd` method to add custom metadata to a comment when a new comment is being added.

        This metadata can be used later to set the position of the Comment Pin.
        You need to set the mandatory `commentType: 'manual'` property to the metadata object.

        ```jsx theme={null}
        <VeltComments onCommentAdd={(event) => yourMethod(event)} />

        const yourMethod = (event) => {
          event?.addContext({ customKey: 'customValue', commentType: 'manual' });
        }

        ```
      </Step>

      <Step title="Retrieve all Comment Annotations">
        Retrieve all `Comment Annotations` using the `useCommentAnnotations()` hook.

        To learn more about the `useCommentAnnotations()` hook, [read here](/api-reference/sdk/api/react-hooks#usegetcommentannotations).

        ```jsx theme={null}
        let commentAnnotations = useCommentAnnotations()
        ```
      </Step>

      <Step title="Render the Velt Comment Pin component and set the position">
        Add the `Velt Comment Pin` component and pass in the `Comment Annotation Id`.
        Now retrieve the `context` to retrieve the custom metadata you set earlier and use it to set the position of the `Comment Pin`.

        ```jsx theme={null}

        let commentAnnotations = useCommentAnnotations()

        return (
        <div className='comments-container'>
          {
            commentAnnotations.map((commentAnnotation) => {
              return (
                <div key={commentAnnotation.annotationId} style={{
                  position: 'absolute',
                  left: commentAnnotation.context.position.x + dragPosition.x,
                  top: commentAnnotation.context.position.y + dragPosition.y,
                  transform: 'translate(0%, -100%)'
                }}>
                  <VeltCommentPin annotationId={commentAnnotation.annotationId}></VeltCommentPin>
                </div>
              )
            })
          }
        </div>
        )
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Other Frameworks">
    <Steps titleSize="h2">
      <Step title="Add custom metadata when comment is added">
        Use the `onCommentAdd` method to add custom metadata to a comment when a new comment is being added.

        This metadata can be used later to set the position of the Comment Pin.
        You need to set the mandatory `commentType: 'manual'` property to the metadata object.

        ```js theme={null}
        const veltCommentsTag = document.querySelector('velt-comments');

        veltCommentsTag?.addEventListener('onCommentAdd', (event) => {
          console.log('*** onCommentAdd ***');
          console.log(event.detail);
          event.detail?.addContext({ customKey: 'customValue', commentType: 'manual'});
        });

        ```
      </Step>

      <Step title="Retrieve all Comment Annotations">
        Retrieve all existing `Comment Annotations` using the `getAllCommentAnnotations()` method.

        To learn more about the `getAllCommentAnnotations` method, [read here](/async-collaboration/comments/customize-behavior#getcommentannotations).

        ```js theme={null}
        const commentElement = Velt.getCommentElement();
        let subscription = commentElement.getAllCommentAnnotations().subscribe((commentAnnotations) => {
          // console.log(commentAnnotations);
        });
        ```

        To unsubscribe from the subscription:

        ```jsx theme={null}
        subscription?.unsubscribe()
        ```
      </Step>

      <Step title="Render the Velt Comment Pin component and set the position">
        Add the `Velt Comment Pin` component and pass in the `Comment Annotation Id`.
        Now retrieve the `context` to retrieve the custom metadata you set earlier and use it to set the position of the `Comment Pin`.

        ```js theme={null}
        const commentElement = Velt.getCommentElement();

        let subscription = commentElement.getAllCommentAnnotations().subscribe((commentAnnotations) => {
          renderCommentAnnotations(commentAnnotations);
        });

        const commentsContainer = document.getElementById('comments-container');

        function renderCommentAnnotations(commentAnnotations) {
          commentAnnotations.forEach((commentAnnotation) => {
            if (!document.getElementById(`comment-pin-container-${commentAnnotation.annotationId}`)) {
              // Add Comment Pin if it doesn't exist
              const { x, y } = commentAnnotation.context.position;
              var commentPinContainer = document.createElement('div');
              commentPinContainer.className = 'comment-pin-container';
              commentPinContainer.id = `comment-pin-container-${commentAnnotation.annotationId}`;
              commentPinContainer.style.left = x + 'px';
              commentPinContainer.style.top = y + 'px';
              commentPinContainer.innerHTML = `<velt-comment-pin annotation-id="${commentAnnotation?.annotationId}"></velt-comment-pin>`;
              commentsContainer?.appendChild(commentPinContainer);
            }
          });
        }


        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

<RequestExample>
  ```jsx React / Next.js theme={null}
  import { VeltCommentPin, useCommentAnnotations } from '@veltdev/react';

  export default function YourDocument() {

    const yourMethod = (event) => {
      event?.addContext({ customKey: 'customValue', commentType: 'manual' });
    }

    let commentAnnotations = useCommentAnnotations()

    return (

      <VeltComments onCommentAdd={(event) => yourMethod(event)} />

      <div className='comments-container'>
        {
          commentAnnotations.map((commentAnnotation) => {
            return (
              <div key={commentAnnotation.annotationId} style={{
                position: 'absolute',
                left: commentAnnotation.context.position.x + dragPosition.x,
                top: commentAnnotation.context.position.y + dragPosition.y,
                transform: 'translate(0%, -100%)'
              }}>
                <VeltCommentPin annotationId={commentAnnotation.annotationId}></VeltCommentPin>
              </div>
            )
          })
        }
      </div>
    )
  }
  ```

  ```html HTML theme={null}
  <script>
  const veltCommentsTag = document.querySelector('velt-comments');

  veltCommentsTag?.addEventListener('onCommentAdd', (event) => {
    console.log('*** onCommentAdd ***');
    console.log(event.detail);
    event.detail?.addContext({ customKey: 'customValue', commentType: 'manual'});
  });

  const commentElement = Velt.getCommentElement();

  let subscription = commentElement.getAllCommentAnnotations().subscribe((commentAnnotations) => {
    renderCommentAnnotations(commentAnnotations);
  });

  const commentsContainer = document.getElementById('comments-container');

  function renderCommentAnnotations(commentAnnotations) {
    commentAnnotations.forEach((commentAnnotation) => {
      if (!document.getElementById(`comment-pin-container-${commentAnnotation.annotationId}`)) {
        // Add Comment Pin if it doesn't exist
        const { x, y } = commentAnnotation.context.position;
        var commentPinContainer = document.createElement('div');
        commentPinContainer.className = 'comment-pin-container';
        commentPinContainer.id = `comment-pin-container-${commentAnnotation.annotationId}`;
        commentPinContainer.style.left = x + 'px';
        commentPinContainer.style.top = y + 'px';
        commentPinContainer.innerHTML = `<velt-comment-pin annotation-id="${commentAnnotation?.annotationId}"></velt-comment-pin>`;
        commentsContainer?.appendChild(commentPinContainer);
      }
    });
  }

  </script>
  ```
</RequestExample>
