From messy feedback chains to a 60-second visual fix loop.
AI SaaS
Own product (snapfeed.app)
2025–2026
Co-founder · Full-Stack
At a glance
A visual feedback SaaS for agencies and teams — embedded as a widget on the client’s live site, no login required.
01 — The problem
Stop losing projects to messy feedback.
Every agency we’ve worked with runs the same broken loop: client opens a Slack DM, drops a vague screenshot, then follows up in email three days later asking why nothing changed. Designers paste comments into Figma frames the client never opens. The PM has to translate “the button thing” into a Jira ticket. Half of every project gets lost in the translation layer between “client sees a thing” and “dev fixes the thing”.
The competitors all knew this. They built tools at $80–$200 per seat, paywalled behind enterprise onboarding, with a learning curve longer than the average feedback cycle itself. So small agencies just kept emailing screenshots back and forth.
SnapFeed exists because somebody had to ship the obvious thing: a widget your client clicks on the live site, paints a circle, hits send, and your team gets a structured bug ticket with everything — screenshot, console logs, browser metadata, the works.
02 — The vision
Point. Click. Done. — the entire feedback experience, distilled.
Three product principles drove every decision:
- Frictionless for the client. No login. No account. No download. They land on the site, see a small floating button, click it, paint on the screen, hit send. The widget knows who they are because the agency configured it for them upfront.
- Structured for the team. Every piece of feedback arrives in the dashboard with a screenshot, an annotated layer, optional video, console errors, the user’s viewport size, the URL, the user agent. The AI pass categorises it (bug / copy / design / question) and suggests severity. Devs open one card and have everything they need.
- Flat pricing for the agency. One price for the whole team, every project, every client. We refused per-seat pricing on principle — we’d been the agency stuck choosing “who deserves a license this month” and we weren’t going to put anyone else through it.
03 — Who it’s for
Built for the people who actually live in the feedback loop.
Web agencies
The original use case. Drop the widget on every client staging site. Clients give feedback where they actually see the work; you get tickets that don’t need decoding.
Freelance developers
Solo devs juggling five clients can’t afford one feedback tool per client. Flat $19/mo covers all of them, all of their projects, every revision round.
SaaS teams
In-house product teams use it for internal QA and beta testing. Same widget, same dashboard, no separate tool for “internal feedback” vs “client feedback”.
Marketing teams
Reviewing the new landing page with five stakeholders? Each one paints on the screen, leaves a note, you triage in the dashboard. Beats a 40-comment thread on a PDF.
04 — The architecture
A monorepo with two apps living on one domain.
Marketing site (Astro 5, fully static) and dashboard (React 18 + Vite SPA) ship as separate builds. Caddy fronts both: path-based routing keeps marketing at snapfeed.app/ and the authenticated app at snapfeed.app/app. One domain, two security boundaries, zero cookie cross-talk. Everything downstream — auth, database, realtime, AI — lives in Supabase plus 23 Edge Functions in Deno.
05 — Technical challenges
Five problems that turned into design decisions.
Two apps, one domain, zero auth bleed
Problem. Marketing is public, the dashboard is authenticated. We wanted both on snapfeed.app for SEO and link equity — not app.snapfeed.app. Naive setups end up with the marketing static build accidentally seeing dashboard cookies, or with Supabase sessions leaking into pages they should never touch.
Solution. Caddy path-based routing: /app/* hits the React SPA container, everything else hits the Astro static bundle. Supabase Auth is scoped per app build via separate storageKey values, so the marketing site literally cannot read dashboard tokens. Cookies are SameSite=Strict and path-scoped. Penetration testing this took a weekend; the production fix took eight lines of Caddyfile.
Embeddable widget on third-party sites without breaking them
Problem. The widget gets dropped on production websites we don’t control. Their CSS uses !important on everything, their JS hooks document.click, their CSP blocks unsafe-inline. Half the existing competitors crash on sites with strict CSP or fight with Tailwind reset rules.
Solution. Shadow DOM scoping for the widget’s entire UI tree — client styles cannot reach inside, our styles cannot leak out. Bundle ships as one ~30KB gzipped file with no external CSS, deferred init, no global polyfills. Event listeners attached only to our own elements. CSP-friendly: no eval, no inline scripts, all assets served from snapfeed.app with explicit CORS headers.
Browser-native video recording without a download
Problem. Clients want to record a video of the bug, not just screenshot it. Existing tools either require a desktop app (Loom, CleanShot) or a Chrome extension. Either way, friction explodes — the client gives up.
Solution. Use navigator.mediaDevices.getDisplayMedia() directly in the page. Local IndexedDB buffer holds the recording while it’s being captured (no upload until they hit send), then chunked upload to Supabase Storage with resumable token recovery. Graceful fallback to screenshot if getDisplayMedia isn’t available (Safari iOS, mostly). Zero plugins, zero installs, works in every modern browser.
AI categorisation that doesn’t destroy the unit economics
Problem. The pitch promised AI-powered triage. The naive implementation — one Gemini call per feedback item — pencils out to a few cents per submission. At $19/mo for unlimited projects, a busy agency could send a thousand items in a month. That’s the entire margin gone.
Solution. Three layers: (1) structured outputs with a JSON schema so Gemini returns exactly the fields we need — no parsing, no retries, no token waste; (2) batch processing — up to 10 feedback items per Gemini call when they arrive within a short window; (3) smart trigger — we only invoke the AI pass when feedback exceeds a length threshold or includes video, otherwise we run a simple keyword classifier. Result: AI cost per active customer stays under a dollar a month.
Real-time dashboard for teams looking at the same project
Problem. Three designers, one PM and a dev all sitting in the dashboard at the same time, triaging incoming feedback. Without realtime, they step on each other’s changes; with naive polling, the dashboard becomes a battery hog and load on the DB explodes.
Solution. Supabase Realtime channels scoped per project — each open dashboard subscribes to row changes for that project only. TanStack Query handles optimistic updates locally so the UI never feels laggy. Conflicts resolved server-side with PostgreSQL INSERT ... ON CONFLICT upserts plus a per-feedback updated_at guard. Two people clicking “resolve” on the same item produce one resolved item, not a race condition.
06 — The workflow
Point. Click. Done.
The entire client experience is three words long. They open the link, see the page they’re reviewing, click the floating button, paint a circle, type a note, hit send. No login screen, no email confirmation, no “please install our extension”. Under a minute, every time.
07 — Feature highlights
Five things the product does, every day, on production.
Each one closes a specific friction point in the feedback loop — from the moment a client sees something wrong to the moment a dev opens the ticket.
+ PWA dashboard
Installable on desktop and mobile via vite-plugin-pwa. Offline-first; new feedback queues locally until the dashboard is back online.
+ Build-in-public marketing
12+ blog posts as MDX content collections in Astro, type-safe frontmatter, free RSS — everything documented from day one.
08 — Stack
Picked for content velocity, runtime predictability and zero ops overhead.
Every tool in the stack earned its place by removing work, not adding it.
docker compose up -d. Predictable, debuggable, cheap.09 — Results
Live, paying, build-in-public.
SnapFeed is in production on snapfeed.app with active Stripe subscriptions, 23 Edge Functions running 24/7, and a marketing blog publishing in the open. We dogfood it daily on our own client projects.
Like what you see?
Let’s build the next one.
From a blank page to a working product — AI, automation, full-stack engineering. Get in touch and let’s talk about your idea.