Anchoring
Attaching a comment to a spot on a living web page is the hardest problem in this product. co-mment treats a pin’s position as a resolution strategy, not a stored coordinate. When a resolution is a guess, the pin says so instead of pretending.
What gets captured
When a comment is posted, the SDK captures an anchor record with three layers:
- Primary: a DOM anchor. A selector chain to the nearest stable element (preferring
id, thendata-testid, then a structural path), plus the click offset within that element as fractions of its box, plus a text fingerprint (the first ~80 characters of the element’sinnerText) used to detect content drift. - Secondary: page-relative position. The click position as a fraction of the full document’s width and height: a fallback, never the preferred answer.
- Context metadata. The exact URL (query and hash included), the normalized path, viewport size, device pixel ratio, scroll position, OS, and browser and version. Metadata informs display and dashboard filters; the DOM anchor drives placement.
How a pin finds its way back
At render time, resolution runs in order:
- Exact. The selector resolves and the text fingerprint matches: the pin is placed at the stored offset inside the element.
- Drifted. The selector resolves but the fingerprint differs: the pin is placed at the element offset and badged “content may have changed”. The element is still there, but what it says has changed since the comment was made.
- Approximate. The selector fails entirely: the pin falls back to the page-relative position and is badged approximate. This is an honest guess: the element the commenter clicked no longer exists.
- Viewport mismatch. Independently of the above, if the current viewport differs from the captured one by more than 20% in width, the pin shows a badge with the original viewport. A comment about a mobile layout viewed on desktop can point at the wrong thing even when the element resolves perfectly.
- Query mismatch. Pins are matched and loaded by path alone. Query string and hash are ignored for matching, but the exact URL is stored. When the captured query differs from the current one, the pin still renders and the thread notes the original URL (“commented on
?plan=annual”). Search results and query-param routing stay visible; mismatches are labeled instead of hidden.
What this means in practice
- Pins survive redeploys, content edits, and responsive reflows far better than pixel-coordinate systems, because the anchor is the element, not the spot on the screen.
- Pins can still be wrong. When a page is restructured heavily, a selector can resolve to a different-but-similarly-addressed element, and an approximate pin on a page whose height changed dramatically can land far from the original intent. The badges exist precisely because no anchoring scheme is drift-proof; treat a drifted or approximate badge as “verify before acting.”
- Stable
idordata-testidattributes on your key UI elements measurably improve anchor quality: the selector chain prefers them over structural paths, which are the most fragile link. - The dashboard shows every thread’s captured browser, OS, and viewport, and can filter by them (“everything reported on mobile Safari”).