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.