Build Guide
How to Build a URL Shortener
A URL shortener with click analytics is one of the fastest paths from idea to paying customers — Bitly charges $35/month for features you can build in 2 days.
URL shorteners teach edge redirects, analytics aggregation, rate limiting, and custom domain routing — a surprisingly rich set of infrastructure patterns in a simple product.
Data model
The core tables you'll need before writing any UI.
Build order
The sequence that minimises rewrites — build in this order.
Slug generation and redirect
Generate a random 6-character slug (nanoid). Store slug → original_url in your database. Create a catch-all route /[slug] that looks up the slug and returns a 301 redirect. Test this works before anything else.
Click tracking middleware
Before the redirect, log a Click row: extract country from the CF-IPCountry header (Cloudflare/Vercel sets this), device from User-Agent, referrer from the Referer header. Do this asynchronously so it doesn't slow the redirect.
Dashboard and link management
Build a dashboard showing all your links with total clicks, creation date, and original URL. Add create and delete actions. Add an edit to update the destination URL without changing the slug.
Analytics per link
Add a detail page per link: total clicks, clicks over time (bar chart last 30 days), top countries (table), top referrers (table), device split (mobile vs desktop donut). Aggregate from the clicks table.
Custom aliases
Let users choose a custom slug (e.g. yourdomain.com/my-product) instead of a random one. Check for uniqueness. Sanitise input to alphanumeric and hyphens only.
Link expiry
Add an expires_at datetime to links. In the redirect handler, check if the link is expired before redirecting. Return a 410 Gone page with a friendly message if so.
QR code generation
Use the qrcode npm package to generate a PNG QR code for each short URL. Return it as a base64 image. Add a download button to the dashboard next to each link.
Build it with AI — Architect Prompt
Paste this into Claude, Cursor, Windsurf, or any AI coding tool. It includes the full context of this guide — data model, build order, and pitfalls — so the AI starts with everything it needs.
<context> App: URL Shortener Difficulty: Beginner Estimated build time: 1–2 days Data model: Link: id, user_id, slug (unique), original_url, custom_alias, expires_at, created_at Click: id, link_id, referrer, country, device (mobile/desktop), browser, clicked_at Recommended build order: 1. Slug generation and redirect — Generate a random 6-character slug (nanoid). Store slug → original_url in your database. Create a catch-all route /[slug] that looks up the slug and returns a 301 redirect. Test this works before anything else. 2. Click tracking middleware — Before the redirect, log a Click row: extract country from the CF-IPCountry header (Cloudflare/Vercel sets this), device from User-Agent, referrer from the Referer header. Do this asynchronously so it doesn't slow the redirect. 3. Dashboard and link management — Build a dashboard showing all your links with total clicks, creation date, and original URL. Add create and delete actions. Add an edit to update the destination URL without changing the slug. 4. Analytics per link — Add a detail page per link: total clicks, clicks over time (bar chart last 30 days), top countries (table), top referrers (table), device split (mobile vs desktop donut). Aggregate from the clicks table. 5. Custom aliases — Let users choose a custom slug (e.g. yourdomain.com/my-product) instead of a random one. Check for uniqueness. Sanitise input to alphanumeric and hyphens only. 6. Link expiry — Add an expires_at datetime to links. In the redirect handler, check if the link is expired before redirecting. Return a 410 Gone page with a friendly message if so. 7. QR code generation — Use the qrcode npm package to generate a PNG QR code for each short URL. Return it as a base64 image. Add a download button to the dashboard next to each link. Known pitfalls to avoid: - Using auto-increment IDs as slugs — they're sequential and predictable. Users can enumerate all links by guessing IDs. Use nanoid() to generate random slugs instead. - Logging clicks synchronously before the redirect — this adds latency to every redirect. Use waitUntil() (Vercel Edge) or a background job to log asynchronously while the redirect fires immediately. - Not handling slug collisions on custom aliases — two users might want the same alias. Always check for uniqueness before saving and return a clear error if the alias is taken. Tech stack (intermediate): Next.js + Supabase + Vercel Edge Middleware for sub-ms redirects + Clerk for teams </context> <role> You are a Senior Full-Stack Engineer and product architect who has shipped production URL Shorteners before. You know exactly where developers get stuck and how to structure the project to avoid rewrites. </role> <task id="step-1-clarify"> Before writing any code or spec, ask me 3–5 clarifying questions that will meaningfully change the architecture. Focus on: scale expectations, auth requirements, platform (web / mobile / both), must-have vs nice-to-have features for the MVP, and any hard constraints (budget, deadline, existing infrastructure). <example> BAD: "What tech stack do you want to use?" — too broad, doesn't change architecture decisions. GOOD: "Do you need real-time sync across devices, or is single-device with periodic refresh acceptable? This decides whether we use WebSockets or simple REST polling and significantly affects infrastructure complexity." </example> </task> <task id="step-2-architect"> After I answer your questions, generate a complete project specification including: 1. Final tech stack with version numbers 2. Full file and folder structure 3. Complete database schema — every table, column, type, index, and foreign key 4. All API routes with request/response shapes and auth requirements 5. Component tree with TypeScript props interfaces 6. Auth and authorisation flow (who can do what) 7. Step-by-step implementation plan in the exact build order from <context> above 8. All environment variables with descriptions <self_check> Before presenting the spec, verify: □ Every answer I gave in step 1 is reflected in the spec □ The database schema matches the data model in <context> □ The implementation plan follows the build order from <context> □ No circular dependencies in the component tree □ Auth is wired up before any protected routes are built □ All known pitfalls from <context> are addressed in the spec </self_check> </task> <task id="step-2.5-agents-md"> Generate an AGENTS.md file at the project root. This file is read automatically by Claude Code, Cursor, Windsurf, Sourcegraph Cody, and all major AI coding tools at the start of every session. Include: - Project overview (2–3 sentences) - Tech stack with version numbers - Folder structure with one-line descriptions - Key architectural decisions and why they were made - Coding conventions: naming (camelCase components, kebab-case files), max 200 lines per file, one concern per file - Available commands: dev, build, test, lint, db:migrate, db:seed Note in the file: "Cursor users can symlink .cursorrules → AGENTS.md. Claude Code users can symlink CLAUDE.md → AGENTS.md." </task> <task id="step-3-implement"> Implement the full project following the spec from step 2, in the exact order defined. For each step: - Write the complete code (no placeholders or TODOs) - Confirm the step is working before moving to the next - Note any deviations from the spec with an explanation <constraints> - Max 200 lines per file. WHY: every file must fit in one AI context window for easy review and editing. - One concern per file. WHY: mixing auth logic into API routes makes it impossible to reuse — extract to lib/auth.ts. - TypeScript strict mode, no `any` types. WHY: catches data shape mismatches at compile time, not in production at 2am. - All database queries in server components or API routes only. WHY: keeps credentials server-side, prevents accidental client-side exposure. - All environment variables documented in .env.example. WHY: the next developer (or your future self) should be able to set up the project in under 5 minutes. - Comment every non-obvious decision. WHY: AI tools read your comments to understand intent — without them, the next edit will break the pattern you established. </constraints> </task>
How to use this prompt
- 1.Copy the prompt above
- 2.Open Claude, Cursor (Cmd+L), or Windsurf
- 3.Paste the prompt and send — the AI will ask 3–5 clarifying questions
- 4.Answer the questions, then it generates your full project spec
- 5.Continue in the same session to implement step by step
Common mistakes
What trips up most developers building this for the first time.
Using auto-increment IDs as slugs — they're sequential and predictable. Users can enumerate all links by guessing IDs. Use nanoid() to generate random slugs instead.
Logging clicks synchronously before the redirect — this adds latency to every redirect. Use waitUntil() (Vercel Edge) or a background job to log asynchronously while the redirect fires immediately.
Not handling slug collisions on custom aliases — two users might want the same alias. Always check for uniqueness before saving and return a clear error if the alias is taken.
Recommended tech stack
Pick the level that matches your experience.
Next.js API routes + Supabase — complete in a day, deploy to Vercel for edge redirects
Next.js + Supabase + Vercel Edge Middleware for sub-ms redirects + Clerk for teams
Next.js + PlanetScale + Cloudflare Workers for global edge redirects + custom domain CNAME support
Take it further — related ideas
Each comes with revenue math, a full build guide, and a prompt to paste into Claude or Cursor.
9 ideas in the archive
ReplayIQ - MCP Server That Injects Live PostHog Session Replay Context Into Claude for Instant UX Diagnosis
You can watch session replays in PostHog all day but Claude has no idea what your users are actually doing. ReplayIQ is an MCP server that pulls live PostHog session replay metadata, event sequences, and rage-click hotspots into Claude's context so you can ask it to diagnose UX failures in plain English. It's like giving Claude eyes on your product.
MenuMap - Drag-and-Drop Menu Builder With QR Code Ordering for Independent Restaurants
Independent restaurant owners are still updating PDF menus by emailing their web developer cousin. MenuMap is a no-code drag-and-drop menu builder that generates a live QR code menu, handles item availability toggles in real time, and optionally accepts orders — all without touching a line of code.
FrameAudit - Autonomous Accessibility Violation Detector for Figma and Live URLs
WCAG compliance is not optional anymore and yet every design review still misses contrast ratios, missing alt text, and focus order chaos. FrameAudit is an AI agent that crawls your Figma file or live URL, detects accessibility violations, and generates a prioritized fix list with code snippets — before your dev team ships the problem.
NoteShip - Shareable Public Pages From Obsidian Notes Instantly
Your Obsidian note is brilliant. Your client cannot open a .md file. NoteShip turns any Obsidian markdown paste into a shareable, readable public URL in one click — like Notion public pages but for people who actually write in Obsidian.
VaultMark - One-Click Obsidian Markdown to PDF and Word Exporter
Obsidian is where your best thinking lives, but sharing it means fighting pandoc on a Friday afternoon. VaultMark lets you paste raw Obsidian markdown and get a clean, formatted PDF or DOCX in under 10 seconds. No CLI, no plugins, no copy-paste degradation.
PawRoute - White-Label Booking App for Independent Dog Walkers
Independent dog walkers are hemorrhaging clients to Rover's 30% commission cut while managing everything via PayPal.me links and texts. PawRoute gives every solo pet care pro their own branded booking page, live GPS walk tracking for anxious owners, and Stripe-powered invoicing.
CoachSlot - Mobile Booking and Payments for Solo Fitness Coaches
Solo yoga teachers and PTs are running $5k/month businesses on WhatsApp and bank transfers like it's 2009. CoachSlot gives every solo fitness coach a personal booking link, Stripe card payments, and automatic cancellation fee enforcement — no more ghost clients.
PageWatch - Affordable Visual and Text Diff Monitor for Journalists and Archivists
The Wayback Machine is great for finding what a site looked like in 2018 — not so great for getting a Slack alert the moment a government agency quietly edits a policy page. PageWatch monitors your URL list daily, generates pixel-level visual diffs and text change extracts, and sends you a digest before your morning coffee.
ArchiveSafe - ChatGPT Conversation Backup Before the Archive Button Destroys Your Work
You spend 3 hours in a ChatGPT thread building something brilliant, click Archive, and poof — good luck finding it ever again. ArchiveSafe is a browser extension that intercepts the Archive action and auto-exports your conversation to searchable Markdown before it disappears. Think Time Machine for your ChatGPT brain.