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

# Context: show your app's data in comments

> Attach and render custom application context in Velt comments and custom UI.

**Context** is arbitrary, customer-defined key-value metadata you attach to a comment/annotation when it's created. Velt stores it on the annotation (`annotation.context.*`), it survives round-trips, and your wireframes can read it. It's the bridge between **your app's domain** (a form question, an invoice line, an email block) and **Velt's comment UI**, and it's how you **scope a comment to a specific element** on the page.

<Note>
  Context values are read in wireframes with the token syntax (`{annotation.context.*}`, `velt-if`, `velt-data`). New to tokens? Read [Template Variables](/docs/ui-customization/template-variables) and [Conditional Templates](/docs/ui-customization/conditional-templates) first. "Page mode" below means the comments sidebar anchored next to specific elements on your page.
</Note>

This is a core customization concept: if your design shows app-specific info in the comment UI (a question title in the dialog header, a "jump to this row" button, a per-element comment), context is how you get that data in.

## Attach context

Every method lands on the same place, `annotation.context`, so your wireframes read them all the same way. Pick by **when you know the value**, then follow the link for params, examples, and merge behavior:

| Method                                                                                                            | Use when                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| [`context` prop](/docs/async-collaboration/comments/customize-behavior#context)                                        | You know the value when you render the component. The common case.                       |
| [`setContextProvider()`](/docs/async-collaboration/comments/customize-behavior#setcontextprovider)                     | The value is derived from the document or location, and every new comment should get it. |
| [`addContext()`](/docs/async-collaboration/comments/customize-behavior#addcontext)                                     | The value is only known at the moment the comment is created.                            |
| [`updateContext()`](/docs/async-collaboration/comments/customize-behavior#updatecontext)                               | The comment already exists and its context changed.                                      |
| [`setContextInPageModeComposer()`](/docs/async-collaboration/comments/customize-behavior#setcontextinpagemodecomposer) | You are driving the page-mode composer yourself.                                         |

Three props do the work on the component side:

* **`context`**: your object, any keys. Lands on `annotation.context`.
* **`targetElementId`**: ties the comment or bubble to a DOM element with that `id`, so the bubble renders on that row. This is how you scope a comment to one element.
* **`contextInPageModeComposer`**: routes the tool's context into the page-mode composer flow ([reference](/docs/async-collaboration/comments/customize-behavior#contextinpagemodecomposer)).

`VeltCommentTool`, `VeltCommentBubble`, `VeltCommentPin`, `VeltCommentComposer`, and `VeltInlineCommentsSection` accept `context`, as do the sidebar and dialog components. Per-component prop lists: [`Props`](/docs/ui-customization/reference/props). To control how a component **matches** existing comments by context, see [`ContextOptions`](/docs/api-reference/sdk/models/data-models#contextoptions).

## Read context in the wireframe

Context is readable via `{…}` tokens: display with `<VeltData field="…">`, branch with `<VeltIf condition="…">`. **The path prefix depends on the surface:**

| Where you're reading it                  | Path prefix                                                                            |
| ---------------------------------------- | -------------------------------------------------------------------------------------- |
| Comment dialog                           | `annotation.context.<key>` (also `commentAnnotation.context.<key>`)                    |
| Page-mode composer (live, not yet saved) | `context.<key>`                                                                        |
| Sidebar focused thread                   | `focusedAnnotation.context.<key>`                                                      |
| Notification list item                   | `notification.notificationSourceData.context.<key>` (or `notification.metadata.<key>`) |

```tsx theme={null}
// custom dialog header: only when the context key exists
<VeltIf condition="!{pageModeComposer} && {annotation.context.questionTitle}">
  <VeltButtonWireframe type="button" id="navigate-to-question-button">
    <VeltData field="annotation.context.questionNumber" />. <VeltData field="annotation.context.questionTitle" />
  </VeltButtonWireframe>
</VeltIf>

// composer header echoing the active context while composing (bare context. path)
<VeltIf condition="{pageModeComposer} && {context.questionTitle}">
  <VeltData field="context.questionTitle" />
</VeltIf>
```

> The custom `id="navigate-to-question-button"` button is wired to app behavior via the `veltButtonClick` bridge ([`Action Components`](/docs/ui-customization/wireframes/action-components)): e.g. scroll to the question.

## What context enables

1. **Scope a comment to a specific element**: `targetElementId` + a matching DOM `id` (e.g. `question-${id}`); a `<VeltCommentBubble targetElementId=…>` then renders that element's bubble in place.
2. **Show app metadata in the comment UI**: question title/number in the header, an invoice line label, an email device/mode badge: straight off `annotation.context.*`.
3. **Conditional UI by domain type**: branch the wireframe on context, e.g. `velt-class="'is-action': {annotation.context.commentType} === 'action'"` or `velt-if="{annotation.context.type} === 'ApproverComment'"`.
4. **Deep-linking / navigation**: a "jump to" button that exists only when a context key is present, handled via `veltButtonClick`.

## Checklist

* [ ] Attached context by the method that matches when you know the value (prop, provider, create event, update, or page-mode composer).
* [ ] Read it with the correct path prefix for the surface (`annotation.context.*` in the dialog, `context.*` in the page-mode composer, `focusedAnnotation.context.*` in the sidebar).
* [ ] Gated context-dependent UI with `velt-if="{…context.key}"` so it only shows when present.
* [ ] Cleared page-mode context after submit/cancel ([`clearPageModeComposerContext()`](/docs/async-collaboration/comments/customize-behavior#clearpagemodecomposercontext)).

<Tip>
  **Have this design in Figma?** The [UI Customization Plugin](/docs/get-started/ui-customization-plugin) for Cursor and Claude Code turns a Figma design into verified Velt UI customization (comments and notifications today): it can generate context-driven wireframes like these from your design.
</Tip>
