Local SEO for a Solo Handyman in Charlotte — From Zero to 9.5× Organic Impressions in 5 Months
How a solo handyman in the Charlotte metro went from zero web presence to 9.5× organic impressions, a top-30 average position, and inbound form leads — using a programmatic Astro site covering 43 cities, 18 services, and 87 ZIP codes.
The Strategic Challenge
A solo handyman with 7+ years of experience and 34 five-star Thumbtack reviews had no website and no organic presence in one of the US's fastest-growing cities. The Charlotte metro spans 5 counties and dozens of towns — too large for a single-page site, too competitive for generic content.
Monthly organic impressions, before → after — Google Search Console.
Key facts
- Client: A solo handyman in Charlotte, NC. 7+ years of experience, 34 five-star reviews, Thumbtack Top Pro badge.
- Scope: website built from zero, local SEO, programmatic location × service pages
- Stack: Astro (SSG), Vercel
- Services covered: 18 — door repair, drywall, cabinet installation, shelving, molding & baseboards, flooring repair, tile work, appliance installation, plumbing, electrical, lighting, picture/mirror hanging, furniture assembly, painting, caulking, smart home, gutter cleaning, deck & fence repair
- Coverage: 43 cities across 5 counties (Mecklenburg, Gaston, Union, Cabarrus, Iredell) + 87 ZIP code pages
- GSC growth (Jan → Jun 2026): impressions 9.5×, clicks 6.7×, average position ~40 → ~28
- Leads: documented inbound form leads went from zero (Jan–Apr) to a steady flow from May onward; phone calls go straight to the owner and aren’t tracked, so the real total is higher
The problem with “one page for everything”
The Charlotte metro is not a single market. Someone searching “handyman Wesley Chapel” is 25 miles from someone searching “handyman Huntersville” — different neighborhoods, different competitors, different intent signals. A site with one service page and one contact form can’t win those searches because Google has no signal that this contractor actually serves that specific town.
The conventional alternative — manually writing a separate page for every city — doesn’t scale. 43 cities × 18 services = 774 combinations. Writing those individually would take months and the content would still be thin.
The programmatic approach
The solution is to separate data from templates. Every city in the Charlotte metro gets a structured data profile: name, county, ZIP codes, neighborhood details, housing type, population context. Every service gets its own data record: name, typical scope, price range, common questions. The templates then generate pages from that data — a unique, accurate page for every city × service combination, at build time.
This produces:
- 43 city pages — each one targeting handyman searches in that specific town
- Up to 774 city × service pages — “flooring repair in Huntersville,” “drywall repair in Waxhaw,” “door repair in Wesley Chapel”
- 87 ZIP code pages — for searches that include ZIP codes or neighborhood-level precision
- 18 service pages — each covering the service across the full metro
All of this is static HTML (Astro SSG), served from CDN, with zero runtime database calls.
Growth over time
The site launched in January 2026. Here is the month-by-month organic trend straight from Search Console, with inbound form leads alongside:
| Month | Impressions | Clicks | Avg. position | Form leads* |
|---|---|---|---|---|
| Jan (from the 4th) | 399 | 2 | 37.7 | 0 |
| Feb | 719 | 4 | 40.6 | 0 |
| Mar | 1,072 | 7 | 33.4 | 0 |
| Apr | 2,096 | 14 | 29.0 | 0 |
| May | 3,348 | 10 | 29.7 | 4 |
| Jun (partial) | 2,605 | 15 | 28.0 | 4 |
*Form leads = genuine service inquiries submitted through the site. Phone calls go straight to the owner and aren’t tracked, so the real total is higher. June is a partial month (through ~the 19th) and already the highest-impression month.
Three curves move together here:
- Impressions compound — 399 → 3,348 per month (June pacing past 4,000), a 9.5× rise as Google indexes and trusts more of the 800+ city × service pages.
- Average position climbs — from ~40 (page four) in the first weeks to ~28 and improving, as the intersection pages earn authority.
- Leads turn on with a lag — the first four months built impressions while positions were still mid-page, so the form stayed quiet. Once average position crossed into the high-20s in late spring, inbound form leads switched on: zero through April, then a steady flow from May — plus untracked phone calls on top.
This is the normal shape of programmatic local SEO: impressions lead, positions follow, conversions come last. Five months in, the curve is still bending up.
Where the rankings are landing
The location × service pages are already hitting the top 10 for specific combinations:
- Huntersville / molding & baseboards — position 4.25 (12.5% CTR)
- Waxhaw / door repair & installation — position 6.5 (25% CTR on impressions)
- Charlotte ZIP 28278 — position 10.96 (top of page 1)
- Broad head query (
handyman near me/handyman charlotte nc) — entered the Top 20 (up from position ~45 on page 5), demonstrating the site’s transition from long-tail city pages to ranking for the highest-volume market keyword.
The homepage is generating the most impressions (5,955) and clicks (20), with the /charlotte/ page close behind (2,439 impressions). The top head query (“handyman near me / charlotte nc”) climbed from page 5 straight into page 2 of search results.
The lead result
The metric that matters isn’t the impression count — it’s the phone ringing and the inbox filling. Documented inbound form leads went from zero through April to a steady flow from May onward, covering real jobs: molding and baseboards, mirror hanging, appliance installation, interior painting, plumbing, drywall and door repair. Phone calls go directly to the owner and aren’t tracked, so the working total is higher than the form alone.
For a solo operator with a capacity ceiling, organic inquiries that arrive with zero ongoing ad spend — and accelerate month over month — are the whole point.
Why programmatic worked here
Programmatic local SEO is not about content spam — it’s about giving Google accurate, specific signals for hundreds of location queries that a single-page site can never cover:
- Entity coverage: each page tells Google which city, which service, which county — structured data makes it machine-readable
- Query specificity: “handyman Waxhaw” and “door repair Waxhaw” are different queries with different intent; one page can only target one of them
- Crawlability: SSG means every page is a static HTML file; Google indexes all 800+ pages without pagination or JavaScript rendering
- Trust signals on every page: same reviews, same credentials, same pricing — not just on the homepage
What was delivered
- Programmatic Astro site (43 cities, 18 services, 87 ZIP codes)
- Structured location and service data layer (5 counties, neighborhoods, housing types)
- Technical SEO: canonical, hreflang-equivalent city alternates, sitemap, LocalBusiness schema, Service schema on every page
- Portfolio and testimonials pages (34 reviews migrated)
- About, guarantee, privacy, terms, service areas pages
- Vercel deployment
This is how we approach local SEO and web development for home-service contractors. A solo operator competing against franchises and aggregators needs a structural advantage — a site architecture that covers the territory. Request a growth audit to see what’s possible in your market.
Results shown are from real engagements and verified in the ad platforms or Search Console. They are specific to each client's market, budget, and sales process — not a promise of similar outcomes. Individual results vary and are not guaranteed.
A note on how we publish cases
"Every number here comes straight from the ad account or Search Console. We name the niche and the market, not the client — their economics stay private, the methodology doesn't."