Loupe.DocsSign in

Documentation

Two packages. loupe-widget is what you install; loupe-core is the anchoring engine inside it, published separately for anyone who wants the primitives without the interface.

Start here

npm install loupe-widget
import { createFeedback } from 'loupe-widget'

createFeedback({
  publishableKey: 'pk_live_…',
  viewerToken: () => fetch('/api/loupe-token').then((r) => r.text()),
  release: process.env.COMMIT_SHA,
})

That is the whole installation. The widget guide covers the script-tag and tag-manager routes, what the options do, and how activation behaves on a production domain.

It shows your visitors nothing. The widget renders only once it has a credential, and on a verified production domain that credential has to come from your server. Shipping it to production is safe on day one.

How it works

A comment is stored as a description of an element — its text, the names you gave it, what it sits between, the shape of the tree above it — rather than as a selector or a pair of coordinates. When the page is loaded again the description is resolved against the current DOM and scored, and the result lands in one of three bands.

BandMeaning
anchoredFound, confidently. The stored description is rewritten to match the page as it is now.
flaggedFound, probably. Shown with a dashed ring and a tooltip saying the element may have changed.
orphanedGone. The pin is never placed at stale coordinates — it is simply not drawn.

The anchoring API documents the primitives, the signals and their weights, and how to tune the thresholds.

Keys

KeyWhere it goes
pk_live_…Your client bundle. It identifies the project, can file a comment, and can read no one else's.
sk_live_…Your server only. Mints the short-lived viewer tokens that let someone read the team's comments.
LP-XXXX-…A join code, typed into the widget once. It enrols that browser; it is not a password.

Mint all three on your project page. Secrets are shown once — only a hash is stored, so there is no second chance to read one.