# How to Leave Anchored Comments on an HTML Report

Canonical: https://commareports.com/comment-on-html

> Pin a comment to a paragraph or a table cell inside a rendered HTML report. Comma adds a Google-Docs-style anchored comment layer outside the iframe — the rendering stays intact.

# How to leave anchored comments on an HTML report

You can comment on a Google Doc. You can comment on a Figma file. You can
comment on a PR. For some reason, you can't easily comment on an HTML
report.

That's a real gap. This page is the answer to it.

## What "anchored" means

A comment is **anchored** when it pins to a specific selection inside the
artifact — not to "the report," but to "the second paragraph" or "the row
with the 8% drop." Click the comment in the sidebar, the surface scrolls
to the anchor. Edit the surrounding content, the comment stays attached
to the same selection.

It's the model Google Docs uses. Comma applies it to HTML.

## Why this is hard for HTML

HTML is rendered. By the time the team sees it, it's a tree of DOM nodes
inside a browser — there's no obvious "comment surface." Two structural
problems make anchoring HTML comments hard:

1. **The HTML may contain scripts and custom layout.** If you inject a
   comment widget into the document, you can break the rendering.
2. **The HTML often changes between revisions.** A row shifts position; a
   chart is regenerated; a paragraph is rewritten. A naïve "anchor by DOM
   path" approach breaks immediately.

Most tools that claim "comment on HTML" either solve only one of these,
or solve both badly. Comma solves both deliberately.

## How Comma does it

Two structural decisions:

### 1. Comments live _outside_ the iframe

The report HTML renders inside an opaque-origin sandbox iframe. The
comment layer renders in the parent page, around the iframe. Comments are
overlaid visually on top of the rendering, but no comment code touches the
HTML itself.

This means:

- **Rendering is faithful.** Scripts, styles, and layout in the source HTML
  run exactly as written.
- **The sandbox is sandboxed.** The HTML can't reach into the user's
  Comma account or read comment data; comment code can't break the
  rendering.

### 2. Anchors are text-based, not DOM-based

A comment anchor is a text selection — the exact characters the
reviewer highlighted. When the HTML refreshes (via a routine or a manual
update), Comma reattaches the comment by finding the same text in the
new revision. Surrounding HTML can change; the comment finds its home.

This means:

- **Comments persist across refreshes.** Last week's open thread on the
  funnel table is still there next week, attached to the same row.
- **Comments survive light edits.** The comment doesn't snap off because
  a sibling div was reordered.
- **Comments degrade gracefully.** If the anchored text disappears
  entirely in a future revision, the comment marks itself as "anchor
  lost" rather than silently floating into the wrong place.

## What you can comment on

Anchored comments work on anything that has text:

- **A paragraph in an executive summary.** Highlight the sentence, pin the
  thread.
- **A table cell.** Click into the cell, leave a comment about the
  number.
- **A chart caption.** Highlight the caption text, ask the question.
- **A code block.** Anchor to a specific line.
- **A header.** Useful for "this whole section needs work."

What doesn't work yet: anchoring to a chart's visual element directly
(the pixels). Those comments need to anchor to the surrounding caption
or table.

## How an agent leaves comments

Comma's MCP server exposes the comment primitives as typed tools. From
Claude Code or Cursor:

```
add_comment(
  report_id: "rpt_…",
  anchor_text: "Q3 conversion dropped 8% week-over-week",
  body: "The drop coincides with the pricing test rollout — see PR #482",
)
```

```
reply_to_comment(
  thread_id: "thr_…",
  body: "Confirmed — rolled back the test, expecting recovery by Friday",
)
```

```
set_comment_status(
  thread_id: "thr_…",
  status: "resolved",
)
```

The agent's comments are first-class — humans see them like any other
reviewer's, including which `comma_sk_…` token authored them.

## How the loop closes

The Google-Docs-shaped review pattern, applied to HTML:

1. **You publish.** Either by hand (paste, upload) or via an agent
   (`create_report` over MCP).
2. **Reviewers comment.** Anchored to the specific text they care about.
3. **You (or the agent) read the comments.** Via the UI, the REST API, or
   `list_comments` over MCP.
4. **You respond.** Edit the HTML (and post a new revision) or reply to
   the thread directly.
5. **Threads resolve.** Marked resolved when addressed. Resolved threads
   stay attached in revision history.

For an agent-driven loop, this is the cycle that closes the feedback
gap most teams give up on.

## What about resolving / @ mentions / notifications

All standard:

- **Resolve / reopen.** Per-thread, by anyone with comment access.
- **@ mentions.** Type `@` to surface teammates from the workspace.
  Mentions trigger an email.
- **Notifications.** New comments, replies, and resolutions email
  participants. Configurable in **Settings → Notifications**.

## Try it

Commenting is free and unlimited — invite as many reviewers per report as
you want. Paste any HTML, send the link to a teammate, ask them to leave one
comment.

**[Create your first report →](https://commareports.com/)**

### Related

- [How to share an HTML report](/share-html-report)
- [Google Docs for HTML](/google-docs-for-html)
- [Stop screenshotting reports into Slack](/stop-screenshotting-reports)
- [Comma MCP server](/mcp)
