Early access · no tracking · 16.3 KB

Point to what broke.

Comment turns “this is broken” into something your team can actually work with. The reporter clicks the problem, leaves a note, and sends the element, route, browser context, console errors, and failed requests with it. No screenshot required.

16.3 KB gzipped 1 origin, 0 third parties 0 cookies 0 page pixels
app.example.com/checkout

Click something on the page to move the mark.

role: geometry: route: /checkout
Color
Mark
Page

The difference

A screenshot shows the page. Comment points to the problem.

Screenshots are useful until someone has to debug from one. Comment keeps the useful part of the report structured: what they clicked, where they were, what the browser was doing, and what failed around the same time.

Typical screenshot toolan image
  • A flattened picture of the page
  • Whatever text happened to be visible
  • Often the full URL
  • A user-agent string
  • Screen coordinates
  • Very little a tool can use directly
comment_ evidence bundle~4 KB of JSON
// feedback.item schema v1 — the anchor, abbreviated
{
  // query string and fragment are stripped before it leaves the page
  "url": "https://app.example.com/checkout",
  "target": { "role": "button", "name": "Place order" },
  "selector": "form:nth-of-type(1) > button:nth-of-type(2)",
  "geometry": { "x_pct": 41, "y_pct": 68,
                "viewport_w": 390, "viewport_h": 844 },
  "markup_color": "red",
  "region": { …drag-selected area, not tied to the pin },
  "markup": [ …freehand strokes as vectors, no raster ]
}

// …and the moment around it
console_error   "TypeError: cannot read properties of undefined"
failed_request  "POST …api.example.com/v2/orders" 502
route_change    "/cart""/checkout"
build_revision  "a91f3c0"

More than one way to find it again

DOM position, accessibility role, accessible name, geometry, and route travel with the mark. If one changes, you still have the others.

Context around the report

Open the panel and Comment starts keeping a short window of clicks, route changes, console errors, and failed requests. Close it and capture stops.

Data, not a flattened picture

Marks are stored as vectors. The issue, timeline, console errors, and failed requests come back as JSON, so people can read the report and software can query the same evidence.

The original evidence stays original

AI can summarize a report. It cannot rewrite what was captured.


Markup

You should be able to see the mark.

Sounds obvious. It isn’t. A highlight that looks great on white disappears on a photo. One that works on dark mode can vanish on a light page. Comment uses layered outlines so the mark keeps its edge without inspecting the pixels underneath it.

Seven colors

Pick whatever makes sense for the review. Red for broken, green for approved, or no system at all. The color stays with the mark.

Change how marks look to you

Glow, high contrast, and color-blind-safe modes are viewer preferences. Comment remembers your choice and can follow the operating system’s contrast setting.

A color-blind-safe palette

The alternate palette is designed to keep marks distinguishable under deutan, protan, and tritan vision. It is applied when marks are viewed in the review overlay and reporter notes.


The loop

From “this is broken” to something you can check.

Someone points at the problem

Send a review link. The reporter opens your site, clicks the thing that is wrong, and leaves a note. No reporter account. Nothing for them to install.

Comment keeps the useful context

The mark, route, viewport, build revision, console errors, and failed requests stay tied to the same reporting session. Automatically captured data is redacted before storage. The reporter’s note is kept as written.

Reproduction checks what it can

Today, Comment can deterministically re-check approved assertions against the evidence already captured. Runs have restricted egress and are recorded for audit.

A person makes the call

Automation can help check a report. It cannot mark the bug fixed. Someone on your team verifies it, and the reporter can follow the status afterward.

Where it stands today: reproduction is offline and deterministic. It works from evidence already captured and does not launch a live browser. Browser-backed reproduction is the next adapter, not a feature we are pretending already exists.


Privacy

Collect less in the first place.

Comment was built around the idea that the best way to protect sensitive page data is not to capture it. There is no screenshot recorder and no code reading what someone types into a field.

  • Page pixels or screenshots
  • A copy of the page’s text
  • Keystrokes or typed input
  • Pointer paths
  • URL query strings or fragments
  • Request or response bodies
  • Headers or cookies
  • Password or payment fields
  • Anything outside the capture window

A few intentional exceptions: Comment keeps up to 80 characters of the marked element’s accessible name. It counts keystrokes and pointer moves for spam detection without storing the keys or movement path. Freehand markup is stored because the reporter explicitly drew it.

Redaction you control

Comment detects email addresses, JWTs, card numbers, and common API-key formats before storage. Add your own deny-terms for the things only your team knows are sensitive. The report records that something was removed and why, not what the value was.

You can tell when capture is running

Open the reporter and you see the recording state. You can stop it before sending the report. If context replay is enabled, a short rolling buffer starts earlier and the feedback button shows that it is active.

Your data is not trapped here

Retention, hard deletion, and tenant-scoped export already exist as API operations. Dashboard controls are still coming. The stack is intentionally ordinary enough to run yourself, though self-hosting is not packaged or licensed yet.

Comment is not session replay, employee monitoring, or a promise that AI will magically find every bug.


Install

One script tag. No unsafe-inline.

The embed comes from one origin. Its UI styles live in constructable stylesheets inside a shadow root, so installation needs script-src and connect-src, not a pile of third-party domains or an inline-style exception.

The whole installation1 tag
<!-- your site, anywhere before </body> -->
<script src="https://api.commentunderscore.com/v1/embed/comment.js" defer></script>

// no project key and no init call. the embed talks to the
// origin that served it, and your site's own origin identifies
// the project. name the launcher if you want to:
//   data-comment-label="Feedback"
What it needs from your CSP2 directives
script-src  'self' https://api.commentunderscore.com;
connect-src 'self' https://api.commentunderscore.com;

// that is the ask: one origin, two directives.
// no 'unsafe-inline'
// no style-src exception
// no font or CDN domains
// no cookies set on your origin
//
// caveat: Safari 16.3 and older have no
// constructable stylesheets. There we fall back
// to an inline <style>, which does need
// style-src 'unsafe-inline' on those browsers.

16.3 KB and checked in CI

The embed is 16.3 KB gzipped. CI measures it against a fixed ceiling and fails the build if it gets too large.

SPA routes without router integration

Comment follows normal page loads and History API navigation without hooking into your router. Hash routes are not distinguished yet.

Reading your own data stays free

Your evidence is available over HTTP and MCP without an upgrade.


Pricing

Reporters are free.

They do not have accounts, so we are not going to turn them into seats. When we start charging, it will be for the things that actually create cost: more capture and more compute.

Free $0 · unlimited reporters
  • Pin, area, and freehand markup
  • Full color palette and appearance modes
  • No-account reporting and reporter status pages
  • Dashboard triage
  • Redaction and consent controls
  • Read API and MCP
Pro More context
  • Everything in Free
  • Context replay from before the reporter opened the panel
  • Console errors and failed requests from that window
  • Email and Slack notifications planned
Expert Reproduction
  • Everything in Pro
  • Bounded automation and reproduction runs
  • GitHub issues and webhooks planned
  • White-labeling and custom intake fields planned

There is nothing to buy yet. No plans, seats, or quotas are live today. We are publishing the shape of the pricing early because changing it now is a lot better than surprising people later.


Questions

The stuff people ask first.

You really don’t take screenshots?

Correct. Comment records which element the reporter marked and the vector markup they added. It does not take a picture of the page.

Do reporters need an account?

No. Send them a review link. It contains a single-use code, and they can follow their report afterward without signing up.

Will this slow down my site?

The main embed is 16.3 KB gzipped, deferred, and served from one origin. Larger features are split into separate bundles and only loaded when they are needed. CI enforces byte limits on those bundles too.

Can I self-host it?

Not as a packaged product yet. The stack is FastAPI, Next.js, and PostgreSQL with no Redis, queue broker, or required managed service. We still need to publish the license and installation path. If self-hosting matters to you, ask us.

Is this session replay?

No. We are trying very hard not to build session replay. Comment captures a short window of interaction metadata around a specific report instead of recording the page or the person’s session.

Will AI reproduce and fix my bugs for me?

No magic button. Today, reproduction checks assertions against evidence that was already captured and tells you what passed, what failed, and what it could not determine. A person still decides whether the bug is fixed.

Give your developers more than “it’s broken.”

Comment is in early access. Tell us what you want to use it on. If it is a good fit, we’ll get you access. If it is not ready for your case, we’ll tell you.

Feedback