Loading
Case study
AI SaaS · own product · agency tools

From messy feedback chains to a 60-second visual fix loop.

Category
AI SaaS
Client
Own product (snapfeed.app)
Years
2025–2026
Role
Co-founder · Full-Stack
SnapFeed landing page — Stop Losing Projects to Messy Feedback
At a glance

A visual feedback SaaS for agencies and teams — embedded as a widget on the client’s live site, no login required.

23
Supabase Edge Functions in Deno
$19/mo
Flat-rate pricing — whole team, no per-seat fees
~30KB
Embeddable widget bundle (gzip)
2apps
Astro marketing + React dashboard, one domain
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.

Built for the teams that build the web — web agencies, freelance devs, SaaS teams, marketing teams. Screenshot of the personas section on snapfeed.app
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.

Marketing site
Astro 5 · SSG · Content Collections
Dashboard app
React 18 · Vite · TanStack Query
Caddy reverse proxy
path-based routing · auth isolation · TLS termination
Supabase backend
Auth · PostgreSQL · Realtime · 23 Edge Functions (Deno)
Stripe
subscriptions · webhooks
Google Gemini 2.5 Flash
categorisation · severity scoring
Deployment
Docker · Caddy · Hetzner VPS · deploy.sh
05 — Technical challenges

Five problems that turned into design decisions.

01

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.

02

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.

03

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.

04

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.

05

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.

SnapFeed workflow section on snapfeed.app — ‘turns chaos into clarity’ with the Point Click Done principle
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.

SnapFeed feature grid on snapfeed.app — Screenshots with precision, Video when words aren't enough, AI that actually helps, No login required, One price for entire team
+ 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.

Layer
Tech
Why
Marketing site
Astro 5 (SSG, content collections)
Blog posts as MDX with type-safe frontmatter. Static output = zero runtime cost.
Dashboard app
React 18 + Vite + TanStack Query
SPA where it matters. Vite for HMR speed; TanStack Query for cache + optimistic updates.
UI
Tailwind + shadcn/ui
Same primitives on both apps. shadcn is owned code, not a dependency we can’t patch.
Backend
Supabase (Auth, Postgres, Realtime, Storage)
Replaces auth + DB + websocket + S3 + serverless in one bill. Edge Functions in Deno = no cold-start surprises.
AI
Google Gemini 2.5 Flash
Structured outputs, low per-call cost, fast latency. Pricing math actually works at $19/mo.
Payments
Stripe (subscriptions + webhooks)
Boring, reliable, every dev knows it. Webhook-driven plan state inside Supabase.
Routing & TLS
Caddy
Path-based routing + automatic Let’s Encrypt + zero-downtime reload. Replaces nginx + certbot.
Deploy
Docker on Hetzner VPS, deploy.sh
One bash script: build → rsync → 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.

Why teams switch to SnapFeed — comparison table from snapfeed.app showing $19 flat pricing vs $80-200+ competitors
Production
Stack live on snapfeed.app since 2025, Stripe subscriptions active.
23 functions
Supabase Edge Functions in Deno covering auth, billing, AI, exports, webhooks.
12+ posts
Build-in-public marketing blog with MDX content collections.
PWA
Installable dashboard, offline queue, works on phone and laptop.

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.