Visual feedback that outlives your markup
Everyone can pin a comment. Almost nobody can keep it pinned.
Click anything on your site and say what's wrong. The difference is what happens next: the comment stays on the element it was left on — through your redesigns, your refactors and your next deploy.
What everyone else pins to
A pin is only as durable as what it points at.
Every tool has to answer one question: which element was this about? Almost all of them answer it with a location. Locations expire. Drag the slider and watch three answers age at different rates.
The page as it was when the comment was left.
Pinned to a coordinate
Stores x: 612, y: 388.
Pinned to a selector
Stores .checkout > .actions > button.cta.
Pinned to a description
Stores the button between the price and the terms link, that says “Buy now”.
What Loupe pins to
Describe the neighbourhood, not the address.
Not div > div:nth-child(2) > button, but the button between the price line and the terms link, inside the checkout region, that says “Buy now”. Nine signals, weighted, scored against every plausible candidate. Renovations change addresses. Descriptions survive them.
captureAnchor and resolveAnchor from the published loupe-core package, in your browser, against real DOM. Each step applies one change to the page and asks the resolver to find the button again. The score is whatever it just returned — including the two steps where it loses.No pin drawn. The comment is in the tray, not on the page.
The comment was left on the Buy now button. This is the page it was left on.
Kills a CSS selector
The build re-hashed every class. Any tool storing .checkout > .actions > button.cta now points at nothing — and this barely notices, because class names were never how it found the button.
Kills a CSS selector · kills an XPath
A flex container appears around the actions. Every path-based answer changed depth. The neighbours did not move relative to each other, which is the only thing being asked about.
Kills nth-child
Terms moves above the button. Any answer holding a child index now points at the link instead. This still finds the button — but watch the bar drop by a fifth, and note that it sits close enough to the line between confident and unsure that the honest thing is to show you the number rather than the label.
Buy now becomes Get started. Text is the most heavily weighted signal, and losing it drops this out of confident and into flagged — where it still lands on the right button, and says out loud that it is no longer sure.
A genuine redesign of the region: renamed, rewrapped, reordered, rewritten. Almost nothing it recorded survived, so it declines to guess. This is the case every coordinate-based tool answers confidently and wrongly.
Nothing to find. The thread is not dropped at stale coordinates — it moves to the orphan tray with its screenshot, to be re-pinned or closed by a person.
Each step is one change to the original page, not a running total. Every score comes from loupe-core running in this tab.
The part most tools skip
It tells you when it isn't sure.
A pin that is confidently in the wrong place teaches people to distrust every pin on the page — and once reviewers stop trusting the pins, they stop leaving them. So every comment lands in one of three states, and the uncertain one is visible rather than hidden.
score ≥ 0.75Anchored
Found it. The stored description is rewritten to match the page as it is now, so it gets more accurate over time rather than decaying.
0.45 – 0.75, or a tieFlagged
Probably this, but the element changed — or two candidates matched equally well. Shown with a dashed ring, and it says so on hover rather than pretending.
below 0.45Orphaned
Gone. Never dropped at stale coordinates and never guessed at — it moves to a tray with its screenshot, to be re-pinned or closed.
What it feels like
One script tag. No account for the person leaving feedback.
They point and say it
A toolbar, not a form. Click an element, drag a region, or capture the whole page when the problem is not about one element. Guests never sign up.
It arrives with the evidence
The viewport it broke in, the device class, the release, and the console tail if you opt in. “It's broken” with nothing attached is what makes a bug unreproducible.
You work it like a board
Cards you can drag, grouped by status, type or priority. Every one links straight back to the live element it was left on.
Measured, not asserted
The resolver has a test suite, and it publishes its score.
The anchoring engine is open source and MIT licensed, so the part you are trusting with your feedback is the part you can read. How the scoring works →
Put it on a staging site this afternoon.
One script tag, one publishable key. It stays completely dormant until someone with a credential asks for it — no launcher, no listeners, no DOM work at all.