codewithtoni
Build in Public

How I Built an AI Website Generator with Next.js and the Claude API

A build-in-public breakdown of the architecture behind an AI tool that finds local businesses without websites and generates sites for them — Next.js, Claude API, Stripe credits, and a built-in CRM.

Antonio Kodheli··3 min read

I spend a lot of time building products, and one of my favorites to engineer was an AI tool that does two things: finds local businesses that don't have a website, and then generates one for them. It's called No-Site Search — the tool I built — and this post is the honest architecture breakdown, including what worked and what I'd do differently.

The problem it solves

Freelancers and agencies who sell websites spend hours prospecting: searching Maps, checking who has no site, pulling contact info, writing pitches. The whole funnel is manual. The idea was to collapse it: search a city + category, get a scored list of businesses with no web presence, and — for the ones worth pursuing — spin up an AI-generated demo site to close the deal.

The stack

  • Next.js (App Router) for the app and all the marketing/SEO surface.
  • Claude API for the generation layer — turning a business's name, category, and details into real site copy and structure.
  • PostgreSQL + Prisma for leads, credits, and CRM data.
  • Stripe for a credit system that covers both lead searches and site builds.

Architecture, piece by piece

1. Finding businesses without websites

The discovery layer queries business listing data, then filters for the signal that matters: no website field, or a dead/placeholder URL. Each result gets a lead score (1–10) based on category, review count, and completeness — so users chase the best prospects first, not just the first ones.

The interesting engineering problem here isn't the query, it's deduplication and freshness — the same business shows up across sources with slightly different names and addresses. A normalization pass (lowercase, strip punctuation, fuzzy-match address) collapses duplicates before they ever hit the UI.

2. Generating the site with the Claude API

Once a user picks a lead, the generation flow sends the business's structured data to the Claude API with a tightly-scoped prompt: produce sections (hero, services, about, contact) as structured JSON, not freeform HTML. Getting the model to return strict, parseable structure is the whole game — I lean on clear schemas and validation, and reject-and-retry when the shape is wrong. The JSON then renders through fixed, well-designed templates, so output quality doesn't depend on the model getting layout right.

3. Credits, CRM, and the moat

A unified credit system (Stripe) meters both searches and builds, which keeps billing simple. The built-in CRM — pipeline stages, notes, activity history, Slack/email alerts — is what turns a one-off tool into something people keep open all day. That stickiness matters more than any single feature.

4. Programmatic SEO

This is the part most relevant to other developers. The app ships 100+ city landing pages (/places/...) and per-vertical pages (/for/restaurants, /for/plumbers), all generated from data at build time. Every page pulls its copy from its own fields so no two are identical — the difference between a legitimate programmatic strategy and a doorway-page penalty. I wrote more about that pattern separately, but the short version: template the layout, never the content.

What I'd do differently

  • Ship the generation schema first. I iterated on prompts before locking the output contract; doing it in the other order would've saved days.
  • Instrument earlier. Knowing which lead scores actually convert should've been in from day one.
  • Treat the CRM as the product. The generator gets attention, but retention lives in the pipeline tooling.

Takeaways for your own build

If you're building anything similar with the Claude API: return structured output, validate it hard, and render through templates you control. Meter usage with credits from day one. And if programmatic SEO is part of the plan, make every generated page genuinely unique from its own data.

You can see the finished product — and try the search yourself — over at No-Site Search below.

The product this post is about — No-Site Search finds local businesses without websites and builds them one.

See No-Site Search live

Written by Antonio Kodheli

Full-stack web developer in Boston. I build modern web apps with TypeScript, Next.js, and the Claude API — and write about it here.