Snagset

Client review for live websites

Your client clicks the thing
that’s wrong, and types.

No account. No extension. No screenshots pasted into email with “the button, second one down”. You get the pin, the element, the screenshot, the console and the route — from a page they were already looking at.

Self-hosted. One <script> tag. Widget is MIT, server is AGPL-3.0.

  1. 1

    Paste one tag

    Into the site you’re building — staging or production, any stack. WordPress, Webflow, Shopify, Rails, Next. There is no framework requirement because it is a script tag.

    <script src="https://review.acme.com/snag.js"
            data-snag-site="prj_…" defer></script>
  2. 2

    Send a link

    Your client opens it and the toolbar is there. They don’t make an account, don’t install anything, and don’t learn a tool — the link is the identity, and it works on their phone.

  3. 3

    Read it in one place

    Every comment arrives pinned to the element, with a screenshot, the browser, the viewport, the route and the console at the moment they clicked. Then rounds: close one, and the page goes clean.

What’s actually different

Your client never signs in

Most review tools ask the person you’re showing work to for an account first. Snagset’s review link carries the identity in its fragment, so it never reaches a server log — and the person giving you feedback does nothing but click and type.

It is your server

One command scaffolds a repo you own, running on Node and Postgres. Comments, screenshots and clients’ words live in your database. There is no hosted tier holding your data and no licence key gating a feature.

One CSP directive

script-src 'self', and only if you don’t already allow same-origin scripts. The widget is served by your own instance and talks back to it — there is no third party for a security team to approve.

Quiet until it’s wanted

A visitor who never opens the toolbar pays for the tag — about 10 kB — and one ~300-byte cached check asking your instance whether review is open. No analytics, no session recording, no telemetry.

Pins that survive a deploy

A comment is anchored by a cascade of strategies, not one brittle selector — so it stays on the element when the class names change, and says so honestly when the element is gone rather than pointing at the wrong thing.

Your agent can read it

An MCP server ships with it, so the assistant fixing the bug can list the open snags and see the element, the route and the console that came with each one — without a human retyping any of it.

Ten minutes, from nothing

npx create-snagset my-review
cd my-review
docker compose up

Postgres comes with the compose file, so there is nothing to provision first. Open the claim URL it prints, add a site, and paste the tag. Already have a database? Put its URL in .env and npm start instead — DATABASE_URL is the only required setting.

The full self-hosting guide →