LocalBusiness Schema

No Comments
Localbusiness schema
TL;DR: LocalBusiness schema is JSON-LD structured data that tells Google exactly what your business is, where it sits, when it opens, and how to reach it. It feeds local knowledge panels and rich results, and it should use the most specific subtype available (Dentist, Restaurant, Plumber), not the generic LocalBusiness. Match it to your Google Business Profile to the letter, then validate with the Rich Results Test.
Check code
RI-006
Category
Structured data
Format
JSON-LD (recommended)
Applies to
Businesses with physical presence or service area
Validation
Rich Results Test

What LocalBusiness schema is

LocalBusiness is a schema.org type, a child of both Organization and Place, that describes a business customers physically visit or that serves a local area. Implemented as JSON-LD in a script tag, it hands Google a machine-readable fact sheet: legal name, street address, coordinates, phone, opening hours, price range, and what kind of business this actually is. Google documents it as a supported rich result feature, and it is one of the schema types where the payoff is concrete: it feeds the local knowledge panel, helps Google reconcile your website with your Google Business Profile, and makes your hours and details eligible to surface directly in search.

This check flags pages representing a local business, typically the homepage, contact page, or location pages, that carry no LocalBusiness markup, or carry a generic Organization type where a specific local subtype belongs.

Why it matters for local SEO

Let me set expectations honestly, because schema vendors oversell this: LocalBusiness markup is not a ranking factor for the local pack. Proximity, relevance, and prominence drive local rankings, and your Google Business Profile is the primary lever. What the markup does is different, and still worth the hour it takes:

  • Entity confirmation. Google builds an entity graph of businesses. When your site's structured data, your GBP listing, and citations across the web all state identical name, address, and phone data, you make the entity unambiguous. Ambiguity is the enemy in local: mismatched data across sources makes Google less confident about every fact it shows.
  • Rich result eligibility. Hours, price range, and review data (when you legitimately have on-page reviews) can surface in knowledge panels and rich snippets. Google's own local business documentation shows hours and business details pulled from markup.
  • Multi-location disambiguation. For businesses with several branches, per-location pages with per-location markup are how you tell Google that the Austin office and the Dallas office are distinct entities with distinct hours and phones, rather than one blurry brand.
  • AI surfaces read it too. Assistants and AI search features that ground answers in structured facts have an easier time recommending a business whose hours, service area, and category are machine-readable. Cheap insurance for wherever local discovery goes next.

The anatomy of a solid implementation

LocalBusiness JSON-LD: what feeds what "@type": "Dentist" "name": "Bright Smile Dental" "address": { PostalAddress } "geo": { lat, long } "telephone": "+1-512-..." "openingHoursSpecification" "priceRange": "$$" "url", "image", "sameAs" on homepage or location page Correct category in knowledge panel specific subtype beats generic LocalBusiness Entity match with Google Business Profile NAP consistency confirms it is the same business Hours and details in rich results open/closed status users act on Machine-readable facts for maps and AI grounding data beyond the classic SERP

How to implement it, step by step

  1. Pick the most specific subtype. Schema.org lists dozens of LocalBusiness children: Restaurant, Dentist, Attorney, AutoRepair, Plumber, HairSalon, and so on. Use the one that fits. Falling back to plain LocalBusiness is acceptable only when nothing closer exists. Specific typing is free relevance information; wasting it is just lazy.
  2. Build the JSON-LD. Google requires name and address as a nested PostalAddress, and recommends geo coordinates, telephone, url, image, priceRange, and openingHoursSpecification. Copy the values from your Google Business Profile character for character, suite numbers and phone formatting included. This is the NAP consistency part, and it is where most implementations quietly fail.
  3. Handle hours properly. Use openingHoursSpecification with dayOfWeek, opens, and closes in 24-hour format. For a 24/7 business, use opens 00:00 and closes 23:59. Remember this markup does not update itself for holidays; GBP special hours handle that.
  4. Place it once per entity. Homepage for a single-location business. For multi-location businesses, each location page gets its own markup with that location's data, and each should link to its own GBP listing. Do not stamp the same head-office address on every page of the site through a theme-wide plugin default.
  5. Connect the graph. Give the business an @id, point url at the canonical page, and use sameAs for your GBP-adjacent profiles (Facebook, Yelp, industry directories). This helps stitch the entity together across the web.
  6. Validate and monitor. Run the page through Google's Rich Results Test for eligibility and the Schema Markup Validator at validator.schema.org for syntax. After deployment, watch Search Console's enhancement and structured data reports for parsing errors. Screaming Frog with structured data extraction enabled will audit markup across all location pages in one crawl.

Property reference

PropertyStatus per Google docsPractitioner notes
nameRequiredExact GBP name. No keyword stuffing, it undermines entity matching.
addressRequiredNested PostalAddress with street, locality, region, postal code, country.
geoRecommendedGeoCoordinates. Pull lat/long from Google Maps for the actual entrance.
openingHoursSpecificationRecommended24-hour format, per-day granularity. Keep in sync with GBP hours.
telephoneRecommendedInclude country code. Same number as GBP, not a tracking number that differs.
priceRangeRecommendedShort form like "$$" or "$10-25". Keep it honest.
image, url, sameAsRecommendedReal photo of the location, canonical page URL, links to official profiles.

Do this, not that

DO

  • Use the most specific subtype (Dentist, not LocalBusiness)
  • Mirror your Google Business Profile NAP exactly
  • Give every location its own page and its own markup
  • Include geo coordinates and structured opening hours
  • Validate with Rich Results Test and re-crawl after changes
DON'T

  • Mark up a business with no physical presence or service area as LocalBusiness
  • Stuff keywords or city names into the name property
  • Let a plugin stamp one head-office address on every page
  • Add aggregateRating without genuine on-page reviews, that risks a manual action
  • Expect markup alone to move local pack rankings

What good looks like

Each location has one canonical page carrying one JSON-LD block with a specific subtype, NAP identical to its Google Business Profile, coordinates, structured hours, and an @id tying the entity together. The Rich Results Test passes clean, Search Console shows zero structured data errors, and when you search the business name, the knowledge panel shows the right category, current hours, and the right website link. Nothing about the markup contradicts anything Google can see elsewhere. Boring, consistent, and machine-verifiable is exactly the goal.

FAQ

Will LocalBusiness schema improve my local pack rankings?
Not directly. Local pack rankings run on proximity, relevance, and prominence, with your Google Business Profile as the main input. The markup's job is entity confirmation and rich result eligibility. It removes ambiguity; it does not add ranking juice.
Should I use Organization or LocalBusiness?
If customers visit a physical location or you serve a defined local area, use LocalBusiness or, better, its most specific subtype. Pure online businesses with no local footprint should stick with Organization. LocalBusiness inherits from Organization, so you are not losing anything by going specific.
How do I handle a service-area business that hides its address?
Google's docs still want an address in the markup, and schema.org offers areaServed for the coverage zone. If you genuinely cannot publish an address, include areaServed and the other properties, and accept reduced rich result eligibility. Do not invent a fake storefront address; that mismatch hurts more than the missing field.
Can I add review stars through aggregateRating?
Only if the reviews are genuinely collected and displayed on that page, and they are not simply copied from Google or Yelp. Self-serving review markup that violates Google's guidelines is one of the most common causes of structured data manual actions I see. When in doubt, leave it out.
One location, multiple pages: where does the markup go?
Put the full LocalBusiness block on one canonical page, usually the homepage or contact page, and reference the entity by @id elsewhere if needed. Duplicating the full block on every page is not penalized, but it multiplies the surfaces where data can drift out of sync, and drift is the real killer.

Not sure if your structured data is helping or quietly contradicting your Business Profile?

An advanced audit validates every schema block on your site, cross-checks NAP consistency against your listings, and flags the errors that block rich results.

Get an Advanced SEO Audit

Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.

About SEO ProCheck

Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.

Work With Me

Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.

Subscribe to our newsletter!

More from our blog