LocalBusiness schema: the markup every local site needs

·4 min read

Local business schema is a block of JSON-LD on your location page that tells search engines your business name, address, phone, coordinates and opening hours in a form they can read without guessing. Google requires only name and address, but the markup earns its keep when you add a specific subtype, geo, openingHoursSpecification and telephone. Put one block on each location page, keep it identical to what the page shows, and never mark up reviews of yourself.

It will not rank you in the map pack on its own. Your Google Business Profile does most of that work. Markup makes your website agree with the profile, and that consistency is the point.

Which local business structured data properties does Google want?

Google's LocalBusiness documentation lists two required properties and a longer recommended set.

Property Status Notes
name Required The business name as customers see it
address Required A PostalAddress with as many fields as you have
telephone Recommended Include the country code
url Recommended The URL of this location's page
geo Recommended Latitude and longitude, at least 5 decimal places
openingHoursSpecification Recommended One object per set of days with the same hours
priceRange Recommended Must be shorter than 100 characters
department Recommended For a store with branded departments
menu, servesCuisine Recommended Restaurants only
aggregateRating, review Recommended Only for sites that review other businesses

Skip the properties that do not apply. An empty menu on a dentist's page helps nobody.

Pick the most specific subtype

Google tells you to "use the most specific LocalBusiness sub-type possible." Schema.org has hundreds of them. A dental practice is Dentist, a pizza place is Restaurant, a garage is AutoRepair, a plumber is Plumber. Plain LocalBusiness is the fallback when nothing fits, and something usually fits.

If you are two things at once, such as a bakery with a cafe, give @type an array: ["Bakery", "CafeOrCoffeeShop"]. Google's doc says additionalType is not supported for this.

Local schema markup example in JSON-LD

Here is a complete block for one location. Paste it in a <script type="application/ld+json"> tag in the page's HTML. If JSON-LD itself is new to you, what JSON-LD is covers the format.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Dentist",
  "name": "Harbor Dental Leeds",
  "url": "https://harbordental.example/leeds",
  "telephone": "+44 113 496 0123",
  "priceRange": "££",
  "image": "https://harbordental.example/img/leeds-front.jpg",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "14 Park Row",
    "addressLocality": "Leeds",
    "postalCode": "LS1 5HD",
    "addressCountry": "GB"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 53.79861,
    "longitude": -1.54532
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "08:30",
      "closes": "17:30"
    },
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday",
      "opens": "09:00",
      "closes": "13:00"
    }
  ],
  "sameAs": [
    "https://www.facebook.com/harbordentalleeds",
    "https://www.yelp.co.uk/biz/harbor-dental-leeds"
  ]
}
</script>

A few details trip people up here.

Coordinates. Google asks for at least 5 decimal places. That is roughly one meter of precision. Copy them from your pin in Google Maps, not from a city-center lookup.

Opening hours. Group days that share hours into one object. For a 24-hour business use "opens": "00:00" and "closes": "23:59". For hours that run past midnight, put the whole shift in one object. Seasonal hours take validFrom and validThrough.

Price range. Keep it short, like ££ or $10-25. At 100 characters or more Google drops it.

The phone and address. Write them exactly as the visible page does. Markup that disagrees with the page is the fastest way to make Google trust neither.

Your Organization block lives elsewhere, usually on the home page. The schema markup guide explains how the types fit together.

Multi-location sites need one page per location

Each location gets its own page and its own LocalBusiness block. Google's doc says to define each location as a LocalBusiness type, and the markup "may make more sense" on a page about that business.

What I see on real sites is the opposite. One "Locations" page holds eight addresses, with eight LocalBusiness nodes stacked in one script. Search engines then cannot tell which address the page is about, and none of the branches gets a page that can rank for "dentist in Leeds." Split them, and set each Business Profile's website field to its own location page.

Self-serving reviews do not get stars

If you mark up reviews or an aggregateRating about your own business, Google will not show stars for them. Google's review snippet guidelines say a page is ineligible for the star review feature when the entity being reviewed controls the reviews about itself. That covers testimonials on your own site, and it covers widgets that pull your Google reviews onto your pages.

The LocalBusiness doc recommends review and aggregateRating only for sites that capture reviews about other local businesses, such as a directory. If that is not you, leave both out. Keep the testimonials as plain text for visitors.

Does local business schema help the map pack?

Not much on its own. Google's help page on local ranking says local results are based on relevance, distance and how well-known a business is, and it talks entirely about your Business Profile and reviews. It does not mention structured data.

So do the profile first. Verify it, pick the right primary category, keep hours current and answer reviews. Then make the website say the same name, address, phone and hours in both the visible text and the markup. The schema is the cheap part, and it still matters for the knowledge panel and for any crawler reading your page, AI crawlers included.

Check your local business markup

Our Local Business Schema Checker reads the LocalBusiness markup on one location or contact page, in JSON-LD or microdata, from the HTML your server sends. It flags a generic LocalBusiness type, an address as plain text or missing fields, a phone without a country code or a tel: link, missing or invalid coordinates, coordinates with fewer than five decimal places, missing or invalid opening hours, a priceRange of 100 characters or more, no listing profiles in sameAs, self-serving review markup and several locations on one page. It also confirms that the marked-up phone and address appear on the page.

Each run costs 5 credits. It does not audit your Google Business Profile, check citations or track rankings.

Keep reading