
Site Gen
Selected work
Make it, ship it, see what worked.
The engine behind our own marketing. Generate on-brand pages, blogs, and emails, then watch what each one actually did.
Built by Pivot & Anchor, a small product studio.- Studio
- A Pivot & Anchor product
- Platform
- Web
- Category
- Marketing & analytics
- Stack
- Next.js, Fastify, Postgres
- Status
- In use across our work
We needed to do our own marketing, and we wanted the same answer every studio wants: which page, which post, which email actually moved someone. So we built the tool that does both halves. It generates the marketing, and it measures it, in one place, against one source of truth.
Three generators sit on a shared brand voice and asset library. Microsite Studio builds on-brand landing pages. Scheduled Blogs writes programmatic SEO posts on a cadence. Emails drafts campaigns with tracked CTAs that point back at the microsites. Everything published carries a four-kilobyte snippet, and the snippet feeds an analytics layer that ties views, scroll depth, clicks, sources, leads, and people back to the exact thing that produced them.
It runs our marketing today, and the tracker is live on work we've shipped, including Enmovil and ProParent. This is a tool we built for ourselves first. It earns its place by being the thing we actually reach for.
From a blank brief to attributed results

01 — Generate
On brand, on demand
One marketing engine, three generators on a shared brand voice and asset library. Microsite Studio builds landing pages, Scheduled Blogs writes programmatic SEO posts on a cadence, and Emails drafts campaigns with CTAs that point back at the pages. A landing page and the email that drives to it read like the same studio wrote them, because they did.
02 — Credits
Metered, topped up in a tap
Generation runs on credits, so the cost of making something is always in view rather than hidden in a monthly bill. Packs scale from a starter tier to agency volume, bought through Razorpay, and the credits never expire. It is the quiet commercial model under a tool that otherwise just feels like asking for what you want.
03 — Measure
See what actually worked
Everything published carries a single lightweight snippet, and that one line wires up attribution end to end. Views, unique visitors, click-through, scroll depth, sources, and time on page roll up per day, and the People, Leads, and Campaigns tabs follow an anonymous session all the way to the lead it became. The question of which page, post, or email produced a result finally has an answer.
What it does
Microsite Studio
Generates on-brand landing pages and microsites from a brief, inheriting the studio's voice and asset library.
Scheduled Blogs
Programmatic SEO posts drafted and published on a cadence, so the content engine runs without a person in the loop each time.
Emails
AI-drafted campaigns with UTM-tagged CTAs that point at the microsites, closing the loop between the send and the page.
Analytics & attribution
Views, scroll depth, CTA clicks, sources, and funnels, tied back to the exact page, post, or email that produced them.
Leads & people
Sessions stitch into people and people into leads, each with a stage and a full activity timeline.
Campaigns
Campaign-scoped, UTM-tagged attribution so the result of one push never blurs into another.
Under the hood, the dashboard is a Next.js app — React 19, TypeScript, Tailwind v4, shadcn — with TanStack Query for server state, Recharts for the metrics, and Tiptap where content gets edited. The design system is dark and cinematic: OKLch colour, one electric-indigo accent, hairline borders, tabular numerics, a light display weight. It runs on Vercel.
The API is Fastify on PostgreSQL with Drizzle, fronted by cookie sessions for the dashboard and API keys for programmatic access, with Swagger docs and rate limiting. Two workers do the heavy lifting on BullMQ and Redis: a generation worker that calls Claude to draft content, and a connection-delivery worker that ships webhooks with retries. The whole backend runs on Railway — API, worker, Postgres, and Redis.
The tracker is the piece we're proudest of. It's a roughly four-kilobyte inline script served from the API that captures pageviews, engagement and scroll, CTA clicks marked with a data attribute, and form submits. It stitches sessions, reads UTM and referrer, hashes IPs, filters bots, and disables itself on localhost. Events ingest into one table, then background jobs roll them up into daily aggregates so the dashboard reads fast no matter how much traffic a page sees.
The hard parts
A tiny, honest tracker
Four kilobytes that capture what matters without following people around. IP-hashed, bot-filtered, off on localhost, no third-party tag.
Ingest, then roll up
High-volume events land in one table; daily rollups on background jobs keep the dashboard instant regardless of traffic.
The generation pipeline
A worker that calls Claude to draft pages, posts, and emails on a shared voice, metered by credits and queued so a burst can't stall the app.
Attribution & lead stitching
Tying anonymous sessions to people, people to leads, and every touch to the campaign that caused it.
Multi-tenant, key-gated
Organizations, users, API keys, and webhook connections, isolated per tenant and documented through Swagger.
One face does the whole product. Open Sans, from a light display weight down to the data, keeps the dark interface calm and legible.
- Open SansEverything — display, UI, and data
A dark canvas, one electric accent, and a small set of semantic states. Colours are authored in OKLch; the hexes below are the closest sRGB read.
- IndigoThe single accent. Primary actions, active states, the one colour that carries the brand.#5B57F2
- Indigo brightHover and emphasis lift on the accent, and the brighter end of chart gradients.#7B79FF
- SuccessHealthy metrics, confirmed states, positive deltas.#2FB888
- WarningSoft alerts, thresholds approaching, things worth a glance.#E0A93C
- DangerErrors, destructive actions, negative deltas.#E8503A
- InkThe dark canvas everything sits on. Hairline borders divide it; tabular numerics sit quietly on top.#14141A

