Run by Claude

City Pages for Contractors: Why One Address Isn't Enough to Rank Everywhere You Work

Google ranks you at your address — unless you tell it otherwise. City pages are how contractors claim territory across their entire service area instead of one zip code.

MurphJune 17, 20265 min read

Most contractors work a 30-mile radius. Most contractor websites only exist — on Google — at one address.

That gap is where your competitor gets the job.

Run a free audit that identifies every city page you're missing →


The Geographic Range Problem

Google starts with one assumption about where you work: your business address.

Your Google Business Profile address tells Google you're in Copley, Ohio. Your website's contact page says the same thing. Nothing else on your site contradicts it. So when someone in Fairlawn (six miles away) searches for "HVAC repair near me," Google ranks the HVAC company with the Fairlawn address — not you, even though you've done fifty jobs there.

This is the default. It's not unfair. It's just a signal problem.

Google isn't filtering you out of Fairlawn results on purpose. It just doesn't have explicit evidence that you operate there. Your competitor who built a /services/hvac-repair/fairlawn-ohio page with real content gave Google that evidence. You didn't.

City pages are how you fix the signal.


What a City Page Actually Is

Not this: your main services page with a city name dropped in at the top.

Not this: a page that says "We also serve Akron, Cleveland, Canton, Medina, and surrounding areas."

This: a dedicated webpage — its own URL, its own title tag, its own H1, its own content — built around a specific service in a specific city.

/services/roof-replacement/akron-ohio
/services/hvac-repair/fairlawn-ohio
/services/tree-removal/cuyahoga-falls-ohio

Each of those pages competes independently for its own keyword. /services/roof-replacement/akron-ohio can rank for "roof replacement Akron Ohio" without needing your homepage to do anything. It's a standalone geographic asset.


Why They Work

When someone in Akron searches "roof replacement Akron Ohio," Google is looking for pages where:

  1. The keyword phrase appears clearly in the URL, title, and H1
  2. The content signals genuine relevance to that city
  3. The page is on a domain Google trusts

You control all three of those. You can build a page that scores high on all three. A page that doesn't exist cannot score at all.

City pages work because they make your geographic footprint explicit. Instead of Google inferring that you might work in Akron based on your Copley address, you're telling it directly: we do roof replacement in Akron. Here's a page about it.

And unlike your GBP (which covers your address and can expand to a service area), city pages live on your website — which means they compound over time, earn backlinks, and work for AI search systems that are reading your content, not your map listing.


What a City Page Needs to Rank

Most city pages contractors build are thin. They copy the main service description, swap the city name, and call it done. Google is good at detecting this — and either ignores the page or treats the whole batch as near-duplicate content.

Here's what a city page needs to actually rank:

Title tag: [Service] in [City, State] | [Business Name] → "Roof Replacement in Akron, OH | Summit Roofing"

H1: [Service] in [City, State] → "Roof Replacement in Akron, Ohio"

A real first paragraph. Not "We provide roof replacement services in Akron Ohio." Something that makes the page about Akron:

Akron's freeze-thaw cycles are hard on roofs. A winter that swings between 15°F and 45°F repeatedly works flashing and shingles in ways that warmer climates don't see — and most of the housing stock in the Merriman Valley and Ellet neighborhoods was built when 20-year shingles were the standard. They're overdue.

That's local. That signals to Google (and to the homeowner reading it) that you actually know this market.

300–500 words minimum. Enough to cover the service, the local context, your process, why you're the right call, and a CTA.

A contact or CTA. Every city page should end with a way to reach you.

LocalBusiness schema with the city in areaServed. This is the machine-readable version of the same signal. See the schema markup guide for how to set it up.


How Many Do You Need?

One per city where you actively want to rank — and where you'd actually pick up the phone if someone called.

For most contractors, that's 5–15 cities. A foundation company working northeast Ohio might build pages for: Akron, Cleveland, Canton, Medina, Cuyahoga Falls, Fairlawn, Strongsville, Hudson, Stow, Kent. That's ten pages. Three to four hours of work. A geographic footprint that could rank in ten markets.

Don't build pages for cities you won't serve. If a lead calls from two hours away and you can't take it, you've wasted a page and trained Google that the page underperforms (because nobody converts from it).

Start with your top five revenue cities — the cities you most often drive to — and build those pages first.


URL Structure for City Pages

This ties directly into the URL structure post. Two patterns work:

Service-first (most common):

/services/[service]/[city-state]
/services/roof-replacement/akron-ohio
/services/roof-replacement/cleveland-ohio

City-first (area-dominant strategy):

/areas/[city-state]/[service]
/areas/akron-ohio/roof-replacement
/areas/cleveland-ohio/roof-replacement

Pick one and stick with it across every city page. Mixed patterns confuse Google's understanding of your site architecture.


The Mistake That Kills City Pages

Spinning 20 identical pages with only the city name swapped.

If your Akron page and your Cleveland page and your Canton page are all the same 300 words with CTRL+F city replacements, Google will detect it. It calls this "thin content" or "doorway pages" — and the response is either ignoring the pages or, in repeat cases, a manual penalty.

The fix isn't writing a novel for each city. It's adding genuine local detail:

  • A neighborhood name: "We work frequently in Highland Square and Merriman Valley"
  • A local context: "Summit County sees more ice dam damage than most of Ohio"
  • A real reference: "Located near the Akron-Canton Airport corridor"
  • A local review pull-quote (if you have one from that city)

Three sentences of local detail on top of your template is enough to differentiate the page. Don't skip it.


City Pages and AI Search

When someone asks ChatGPT "who does tree removal in Cuyahoga Falls" or asks Google "best HVAC contractor near Fairlawn," AI systems are crawling the open web for pages that explicitly connect your business to that location and service.

A city page is the clearest possible signal. URL says it. H1 says it. Content confirms it. Schema declares it.

Without city pages, AI search has to infer your service area from your homepage, your GBP listing, or wherever else your name shows up. That inference is often narrower than your actual range — and the contractor who built the explicit page wins the citation.

This same principle applies to title tags, schema markup, and URL structure: be explicit. Don't make Google guess.


How Our Audit Identifies Your Missing City Pages

The brand audit at /start includes a Missing Pages module. It looks at your current site structure, identifies the cities in your service area (from your GBP and site content), and compares against the city pages you've actually built.

If you're working Akron, Cleveland, and Canton every week but only have pages targeting one of them, the audit surfaces that gap — along with the exact page structure and content angle to fill it.

It's a 2-minute form. Free. You get the full report in your inbox.

See which city pages you're missing →


This is part of an ongoing series on local SEO for contractors. Related: Services Pages, URL Structure, Schema Markup.

Want to see how your business stacks up?

Get a free brand audit — we'll show you what's working, what's not, and what to fix first.

Free Brand Audit →
Jason Murphy

Written by

Murph

Jason Matthew Murphy. Twenty years building digital systems for businesses. Former CardinalCommerce (acquired by Visa). Now running VibeTokens — a brand agency for small businesses that builds websites, content, and growth systems with AI.

Live Workshop · April 27

Build your Claude OS in 4 hours. CLAUDE.md, MCP servers, 3 custom workflows. 8 seats, $247.

Reserve Seat →

Your brand is your first impression.

Find out if it's costing you customers.

Free brand audit. We analyze your online presence, competitors, and messaging — then tell you exactly what to fix.

Get Your Free Brand Audit →