Local Schema Markup
Last updated
Local schema markup uses schema.org types to declare a business’s identity, location, services, and operational details to search engines explicitly. For local businesses, well-implemented schema reinforces the entity Google recognises through Google Business Profile and citations, and earns local rich results in search.
The core local schema types
LocalBusiness. The base type for any business with a physical location or service area. Sub-types extend it with industry-specific properties: Restaurant, Plumber, Dentist, LegalService, FinancialService, and many others. Use the most specific sub-type that fits.
PostalAddress. Required nested type for the business’s address. Includes streetAddress, addressLocality, addressRegion, postalCode, addressCountry.
OpeningHoursSpecification. Declares opening hours per day. More precise than the simpler openingHours string property; supports varying hours per day, holiday hours, and seasonal variations.
GeoCoordinates. Latitude and longitude. Useful for ensuring map placement matches your intended location precisely.
Service. For service-based businesses, declares the specific services offered. Each service can be its own structured entity with description, area served, and price information.
AggregateRating and Review. Star rating and review counts, with individual reviews. Eligible for star rich results in some contexts; subject to recent Google restrictions on self-serving review markup.
A worked example
A typical local business schema for a plumbing company:
{
"@context": "https://schema.org",
"@type": "Plumber",
"@id": "https://example-plumber.co.uk/#business",
"name": "Example Plumbing Services Ltd",
"image": "https://example-plumber.co.uk/logo.jpg",
"url": "https://example-plumber.co.uk/",
"telephone": "+44 117 946 0958",
"priceRange": "£££",
"address": {
"@type": "PostalAddress",
"streetAddress": "12 High Street",
"addressLocality": "Bristol",
"addressRegion": "England",
"postalCode": "BS1 1AA",
"addressCountry": "GB"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 51.4545,
"longitude": -2.5879
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "08:00",
"closes": "18:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": "Saturday",
"opens": "09:00",
"closes": "13:00"
}
],
"areaServed": [
{ "@type": "City", "name": "Bristol" },
{ "@type": "City", "name": "Bath" }
],
"sameAs": [
"https://www.facebook.com/exampleplumber",
"https://www.linkedin.com/company/example-plumber"
]
}
This schema would typically sit in the <head> of the homepage and the contact page. For multi-location businesses, each location’s landing page would carry its own LocalBusiness schema with that location’s specific details.
NAP consistency between schema and other sources
The address, phone, and name in your schema must match exactly what’s in:
- Your Google Business Profile
- Your major local citations
- The visible NAP on your website
Mismatches confuse Google’s entity matching and dilute the local signal. Audit periodically; updates to GBP or citations should trigger a check on the on-site schema.
Service area vs physical address
For businesses without a customer-facing physical premises (most tradespeople, mobile services, consultants):
- Use
areaServedto declare the cities or regions covered - Omit or de-emphasise
addressif the address is a residential or otherwise non-public location - Consider whether
LocalBusinessis the right type at all; some service businesses fit better underProfessionalServiceor a more specific sub-type
Google Business Profile distinguishes between businesses with a public address and service-area businesses. Schema should align with the GBP setup.
Multi-location schema
For businesses with multiple physical locations, the standard pattern:
- A separate LocalBusiness schema block on each location’s landing page
- Each block has a unique
@id(typically the URL of the location page plus#business) - The parent organisation can be declared with Organization schema referencing all the locations via
branchorsubOrganization
This structure lets Google understand both the individual locations and the parent brand without conflating them.
Service schema for service-based businesses
For businesses where services are a primary search target, Service schema lets each service be its own entity:
{
"@type": "Service",
"name": "Boiler Installation",
"provider": { "@id": "https://example-plumber.co.uk/#business" },
"areaServed": { "@type": "City", "name": "Bristol" },
"description": "Professional gas-safe boiler installation across Bristol, including system design, removal of old units, and full commissioning."
}
Service schema is especially useful for service-area businesses targeting “[service] in [city]” queries. Each service can declare its own area served, allowing the same business to appear relevant for different services in different cities.
Common local schema mistakes
| Mistake | Effect |
|---|---|
| LocalBusiness schema on a non-local business | Misleading; doesn’t help; can confuse entity matching |
| Schema NAP doesn’t match GBP NAP | Diluted entity signal |
| Wrong country code in postalAddress | Geographic misrouting |
| Self-serving aggregateRating without genuine reviews | Manual action risk |
| Schema for a service area that doesn’t match GBP service area | Conflicting signals |
| Multiple LocalBusiness schemas on the same page | Confusion; one will be picked arbitrarily |
Validation
Use both:
- Schema Markup Validator for spec validity
- Google Rich Results Test for Google-specific eligibility
Local rich results (knowledge panel content, map placements, hours displays) require that the schema validates and matches Google’s policies. Both validation steps are necessary.
Frequently asked questions
Does local schema directly improve local pack ranking? Indirectly. Schema reinforces the entity signal Google uses to evaluate the business; the local pack ranking factors are largely off-page (GBP, citations, reviews, links). Strong schema supports those signals; it doesn’t substitute for them.
Should I add LocalBusiness schema to every page? A condensed version on every page is acceptable; the full version belongs on the homepage and contact page. For multi-location sites, the location-specific page should carry that location’s full schema.
What about hours that vary?
Use multiple openingHoursSpecification entries for different patterns (weekday vs weekend, summer vs winter). For temporary closures or special hours, the specialOpeningHoursSpecification property handles holiday and one-off variations.