Website feedback with the whole story attached.
Clients click any element and type a comment. Pencilmark attaches the selector, styles, console errors and page state — then AI drafts the fix. No screenshots to decode, no “which button?” threads.
one script tag · any website · clients need nothing
“the buy button is invisible on my phone??”
Sarah · client · magic link
Why another feedback tool
Screenshots show what happened. They never explain why.
Feedback tools split into two camps, and both leave you doing the decoding.
Screenshot-first tools
You get a JPEG and “this looks weird.” The what, never the why — you open devtools anyway and hunt for the element by eye.
Ticket forwarders
Feedback survives the trip to your tracker, but the context doesn’t. The loop lives in someone else’s tool, and the client can’t see progress.
Pencilmark
Structured DOM data on every comment, a built-in inbox with a real lifecycle, and AI that turns raw feedback into drafted tasks. Nothing to decode.
The capture payload
Every comment carries its own evidence.
The capture payload is the product. What lands in your inbox is a reproducible report, not an image to squint at.
Locators that survive redesigns
Every annotation stores a multi-strategy selector chain — id and data-attribute paths, CSS path, nth-of-type — plus a quoted text anchor. Pins re-attach after the DOM shifts; when nothing matches, the annotation says so honestly instead of pointing at the wrong element.
Element fingerprint
Tag, classes, ARIA role, bounding box, and the computed styles that matter — with hex values and cascade-verified custom properties, so var(--brand-primary) resolves to what actually rendered.
Console & network, attached
Errors and failed requests since page load ship with the comment, masked for PII by default. The bug report arrives with its own stack trace.
DOM snapshots, not just pictures
The annotated subtree is serialized — scripts and form values stripped, styles inlined, size-capped — and re-rendered in a sandboxed frame in your dashboard. See the element as the client saw it, no host CSS required.
Pins that live on the page
Open, in progress, resolved — pinned to the element and synced on a 30-second poll. Clients watch their feedback get handled while they’re still on the site.
Client-simple, developer-deep
Reporters click and type; they never meet a selector. Open the technical pane and everything is there: locator strategies, fingerprint, environment, snapshot.
Three steps
From snippet to shipped fix.
Setup is the same whether the site is yours or a client’s — and the client’s part is just clicking.
- 01
Paste one snippet
Drop the script before </body> on the site under review — WordPress, Shopify theme, PHP, static HTML, any SPA. It boots after the DOM is ready and renders inside a shadow root, so hostile themes can’t touch it and it can’t touch them.
- 02
Invite your client
A magic-link invite per project. They click an element, select text, or drag a region, then type. No account, no extension, nothing to learn — identity is captured on submit.
- 03
Triage and ship
The inbox groups feedback by page with statuses, assignees and threaded comments. AI titles and dedupes as reports land, drafts the task, and exports agent-ready markdown when it’s time to build.
<script src="https://cdn.pencilmark.dev/widget.js?v=0.7.1"></script>
<script>
(function (w) {
var args = { token: "YOUR_PROJECT_TOKEN", endpoint: "https://app.pencilmark.dev/api/v1/annotations" };
(function boot() {
if (w.PencilmarkWidget && w.PencilmarkWidget.init) w.PencilmarkWidget.init(args);
else setTimeout(boot, 50);
})();
})(window);
</script>Your real snippet — with the project token and live endpoints — is on the dashboard’s Install page, with an install verifier that confirms check-ins per origin. WordPress mu-plugin and Shopify app-embed guides included; extension and bookmarklet tiers cover sites you can’t edit.
The AI layer
From “the button looks weird” to a drafted ticket.
AI consumes the structured payload — the advantage of not being screenshot-first. Enrichment runs as feedback lands; dedupe and exports run when you ask.
In
“the buy button is invisible on my phone??”
#14 · /checkout · Sarah (client) · mobile
Out — draft task
Submit button on /checkout invisible at mobile widths
color:#fff on background:#fff below 420px; TypeError at checkout.js:214 attached. Suspected cause: contrast lost in the 390px breakpoint stylesheet.
Auto-title & summarize
“Comment #14” becomes a sentence that describes the bug.
Dedupe & cluster
Five reports about the same header become one thread with linked duplicates.
Feedback → task drafts
Reporter words + element fingerprint + console errors = a concrete issue with a suspected cause.
Agent export
One click produces agent-ready markdown. An MCP server for pulling open feedback straight into your coding agent is next.
Bring your own OpenAI-compatible key (AI_BASE_URL / AI_MODEL) — or point it at a small self-hosted classifier for automatic triage. With no key set, every AI feature stays cleanly off and nothing leaves your deployment.
Positioning
Where Pencilmark sits.
An honest read of the two camps this project lives between — screenshot-first annotators and ticket forwarders.
| Capability | Screenshot-first tools | Ticket forwarders | Pencilmark |
|---|---|---|---|
| Runs on any website | framework-locked | script tag | script · extension · bookmarklet |
| Selectors, styles & position on every report | a JPEG at best | on higher tiers | core — every annotation |
| Zero setup for clients | devtools required | Yes | magic-link invites |
| Built-in feedback lifecycle | pipes to your agent | forwards to trackers | inbox · statuses · threads |
| AI: summarize, dedupe, draft tasks | your agent’s job | No | built in, BYO key |
| Self-hostable | No | No | docker-compose, your Postgres |
FAQ
Questions, answered plainly.
How Pencilmark behaves in the environments that break other feedback tools.
What do my clients have to install?
Nothing. They get a magic-link invite per project and comment directly on the live site — click an element, select text, or drag a region, then type. No account, no extension, no training call.
Does it work on WordPress, Shopify, my stack?
If you can add a script tag before </body>, yes — WordPress, Shopify storefront themes, PHP, static sites, and any SPA. The widget boots after the DOM is ready and re-locates its pins on route changes. For sites you can’t edit (strict CSP and friends), browser-extension and bookmarklet install tiers are on the roadmap.
What happens when the DOM changes before the fix ships?
Each annotation carries a multi-strategy locator — id/data-attribute paths, CSS path, nth-of-type — plus a quoted text anchor. Pins re-attach after most changes; when every strategy misses, the annotation shows an honest “element changed” state with its DOM snapshot. Never a pin floating over the wrong element.
Do annotations include screenshots?
Optionally, as a fallback — never the source of truth. The structured capture (locator, fingerprint, environment, DOM snapshot) is what makes a report reproducible. When a CORS-tainted canvas blocks the screenshot, the annotation still goes through with everything else attached, clearly labeled.
Is console and network capture safe for client data?
It’s masked by default: form values and common PII patterns are stripped before anything is stored, log windows are bounded, and each project controls which URL parameters are kept.
Can I self-host?
Yes. The project ships as a docker-compose deployment — Next.js + Postgres, migrations on boot — that runs anywhere Docker does. Annotations, snapshots and screenshots stay on your infrastructure, end to end.
What does it cost?
Free while in beta. Pricing lands with the hosted version; self-hosting stays available for teams that want their data in-house.