Show HN: Pitchkit – Send a website redesign instead of cold calling(pitchkit.dev)
pitchkit.dev
Show HN: Pitchkit – Send a website redesign instead of cold calling
https://pitchkit.dev/
2 comments
A few technical decisions that might be worth discussing:
The two-pass split was non-obvious at first. The initial version sent scraped content directly to a generation prompt and got inconsistent, generic results. The problem was the model was doing two hard things simultaneously — understanding the business and designing for it. Splitting those into separate API calls with a structured JSON handoff between them fixed it. Pass 1 now returns explicit values (hex codes, font names, ordered section list) that Pass 2 treats as hard constraints rather than suggestions.
The pageStructure extraction changed the output quality more than any prompt engineering did. Previous versions used a hardcoded template — hero, services, about, contact — regardless of what the original site actually had. Now Pass 1 reads the real site and returns the actual sections in order. The redesign inherits the client's real information architecture. When a business owner sees their own menu categories, their real phone number, their actual service list — it lands completely differently than a generic template with their name swapped in.
On scraping: Playwright handles most sites reliably. The Google Maps flow is interesting — instead of scraping a website, Pass 1 pulls from the Maps listing (name, category, photos, reviews) and generates a design from that. Works well for businesses with no website at all, which turns out to be a bigger market than I expected.
The bot protection problem is the thing I haven't solved well. Happy to go deeper on any of this.
The two-pass split was non-obvious at first. The initial version sent scraped content directly to a generation prompt and got inconsistent, generic results. The problem was the model was doing two hard things simultaneously — understanding the business and designing for it. Splitting those into separate API calls with a structured JSON handoff between them fixed it. Pass 1 now returns explicit values (hex codes, font names, ordered section list) that Pass 2 treats as hard constraints rather than suggestions.
The pageStructure extraction changed the output quality more than any prompt engineering did. Previous versions used a hardcoded template — hero, services, about, contact — regardless of what the original site actually had. Now Pass 1 reads the real site and returns the actual sections in order. The redesign inherits the client's real information architecture. When a business owner sees their own menu categories, their real phone number, their actual service list — it lands completely differently than a generic template with their name swapped in.
On scraping: Playwright handles most sites reliably. The Google Maps flow is interesting — instead of scraping a website, Pass 1 pulls from the Maps listing (name, category, photos, reviews) and generates a design from that. Works well for businesses with no website at all, which turns out to be a bigger market than I expected.
The bot protection problem is the thing I haven't solved well. Happy to go deeper on any of this.
So I built a pipeline to do the pitch for me.
You paste a URL or Google Maps link. Playwright scrapes the site — content, images, structure, screenshot. That feeds into a two-pass Claude API flow:
Pass 1 returns a structured JSON profile of the business plus a pageStructure array — an ordered list of the site's actual sections in sequence. A plumber gets "Hero with emergency CTA, Services list, Service area, Reviews, Free estimate CTA." A restaurant gets "Menu highlights, Photo gallery, About the chef, Reservation CTA." The redesign mirrors this exactly rather than defaulting to a generic template.
Pass 2 takes a selected style direction with explicit hex codes and Google Font pairings as hard constraints — not prose descriptions — and generates the full HTML. Separating analysis from generation was the biggest quality unlock. Single-pass kept producing generic output because the model was guessing business context while simultaneously designing.
The output is a shareable preview link. Cold email becomes: "I noticed your website, I redesigned it, here's the link." No pitch. No call.
Biggest unsolved problem: bot protection. Playwright with stealth handles most sites but Cloudflare Enterprise stops it cold. Curious if anyone has approaches that work reliably at scale without getting into residential proxy territory.
Stack: Next.js 14, Supabase, Playwright, Claude API, Railway.
Free credits at pitchkit.dev — no card required. Feedback on redesign quality especially welcome, that's the thing I'm most focused on improving.