Design Lab / project
The free site campaign
Same play as my dad's diecast shop, industrialized. Find Chicago businesses that do good work and have a bad or missing website. Build each one a site before I ever meet them. Print a card with the link and a QR code, and walk in. The site is the pitch. The lead is the byproduct.
Finding them
Google already knows who has no website.
The Places API returns, for every business, whether it has a website URL, its rating, and how many people rated it. So the search is one line: high rating, real review count, no website. Twenty-two niches (hardware, upholstery, small engine repair, furniture, lawn care, the trades) across rings of Chicago neighborhoods, starting with my own.
Then a scorer checks the ones that do list a site. A domain that resolves to a parked page, a dead Wix, or a Facebook link counts as no website. That is where most of the opportunity is: not the businesses with nothing, the ones with something embarrassing.
The whole harvest cost about the price of a nice lunch. The API bills per request, one request returns twenty businesses, and going deeper on a narrow query is cheaper than going wider.
harvest.py Places API (New), text search
22 niches x neighborhood rings
fields: website, rating, ratings count
--> 2,112 rows in SQLite
clean.py flag, never delete
wrong industry (car shops as "small engine")
wrong place (Humboldt Park -> Humboldt County CA)
not a business (Home Depot, a monument)
--> 1,539 real leads
score.py opportunity = rating x reviews x no-site
dead / parked / facebook-only = no site
--> 119 A-List
make_sites.py one static site per lead
--> 109 built, live on Cloudflare Pages
cards 5x7, front + back, QR to their site
--> 20 doors, two days, mapped by drive The list
The first spreadsheet was beautiful and a third wrong.
"Small engine repair" is a phrase to Google, not a category. A quarter of those rows were car mechanics, sitting at the top with five stars and no website. Filtered by the type Google assigns, not the phrase I searched.
Searching "Humboldt Park, Chicago" returned Humboldt County, California. A funeral home in Eureka was a lead, 1,939 miles out. 257 rows sat more than 45 miles from the Loop. Distance filter, not a state filter.
"Monument" as a Google type means a landmark. Millennium Monument was a lead. So were three Home Depots and a Macy's. Chains and landmarks get flagged, and every flag is kept so the exclusion is auditable.
The lesson, same as always: a plausible-looking answer is not a verified one. Eyeball the top fifteen by name before you print anything.
The route
Twenty doors, two days, in the car.
From the A-List: rating 4.3 or better, a real review count, open, a built site. Two city-run senior centers cut. They are not sales targets.
Day one is the north and northwest side, about 31 miles, two of them under a mile from home. Day two is the south corridor.
5x7, colour, front and back. The front is their site. The back is the pitch, in my voice, and a QR. Say less, point at the QR.
Hardware stores open early, upholstery shops open whenever. Check their site on your phone in the parking lot. You are about to stand next to the owner while it loads.
If they bite: the site moves to their own domain for free, they buy the ten-dollar domain. Then a care plan. Then "who does your IT?" The 109 stay private until a shop says yes.
Run a shop with no website, or a bad one?
You might already have a site waiting. Quick IT, free 30-minute consult.