Skip to content
KKAELUM STUDIO
← All entries
11 April 2026 · 2 min read

Programmatic geo SEO for service businesses

How to template-build hundreds of locally relevant pages without sounding like a thin-content farm.

"Programmatic SEO" has a reputation, mostly earned, for being the seediest corner of organic growth. Take a template, multiply by a CSV of cities, ship 1,400 indistinguishable landing pages, watch Google de-rank you a quarter later.

But the underlying technique — generating many semantically distinct pages from structured data — is exactly how Yelp, Indeed, and Zillow built their organic moats. The question isn't whether to do programmatic. It's whether each generated page actually deserves to exist.

The cheap version

The cheap version reads like this: "Plumber in Slough. Looking for a plumber in Slough? Our Slough plumbing team has been serving Slough since 2008. Call 0800 …".

Google can identify this with a bag-of-words classifier. So can your customer.

The version that ranks

A good programmatic page is structurally identical to its siblings, but every one of these slots carries real information:

  • A unique opening sentence tied to a local landmark, industry, or context. ("Harlow is one of the few new towns in Essex with a working CDN POP, which means…")
  • Postcodes and a geographic boundary, expressed as JSON-LD LocalBusiness with a GeoCoordinates block.
  • A handful of true local references: industries that thrive there, distance from the studio, a real map.
  • A FAQ with town-specific answers — not "Do you do plumbing?" but "Will the site rank in Harlow on Google?".

If you can't find at least four pieces of unique-per-town information, the page should not exist.

The architecture we use

For service businesses with under ~50 target locations, we ship a single dynamic route, statically generated at build time:

// app/web-design/[town]/page.tsx
export function generateStaticParams() {
  return LOCATIONS.map((l) => ({ town: l.slug }));
}

Each LOCATIONS entry carries postcodes, lat/lng, an anchor industry, a landmark, and distance. The page then renders:

  1. Hero with the town name and a one-sentence local hook.
  2. A Mapbox static image centred on the town.
  3. The town-specific FAQ block (with FAQPage schema).
  4. A list of neighbouring towns, computed by Euclidean distance from the lat/lng, with internal links.

This last point matters more than the rest: a tight, programmatically generated internal link graph between geographically adjacent pages is the single biggest thing we've shipped that moves rankings.

What it actually delivers

For GM Electrical, we shipped 146 town pages on this pattern. Eleven weeks later, the site held position one for the "main town + trade" query in 38 of those towns, and a top-three position in 92 more. Phone-call volume increased 4.6×.

We didn't write 146 unique blog posts. We engineered an information architecture where 146 pages each carried their weight.

What we won't do

We won't ship programmatic content where:

  • The business cannot actually serve the listed locations.
  • The local information is invented or vague.
  • The pages would not survive a manual quality rater's read.

Programmatic at scale is a privilege a brand earns. Get the first ten pages right, then template the next 140.