Schema Markup for Local Service Businesses: A Cheat Sheet
The exact schema types every local service business needs in 2026: LocalBusiness, Service, FAQ, BreadcrumbList. Real JSON-LD examples you can paste.
By Chase Weiser
Most local service sites I audit have either no schema or schema that fails validation. Both outcomes look the same to Google: nothing to render, nothing to trust. The good news is that for a typical local business, you only need four schema types to cover the meaningful rich result surfaces and AI search citations. This page is the copy-paste reference I use when building a new client site and when retrofitting structured data onto existing ones.
Every example below is valid JSON-LD as of the March 2026 Schema.org spec. Run anything you ship through Google’s Rich Results Test (search.google.com/test/rich-results) and the Schema.org Validator (validator.schema.org) before pushing to production. Rich Results Test catches what Google specifically renders. The Schema.org Validator catches type errors the search-side tool will quietly ignore. You want both green.
1. LocalBusiness with full NAP, geo, hours, and service area
This is the foundation. Every page on a local business site should reference one canonical LocalBusiness node, usually via @id. Use the most specific subtype that fits: Plumber, Electrician, RoofingContractor, Restaurant, LegalService, etc. If nothing fits, fall back to LocalBusiness.
{
"@context": "https://schema.org",
"@type": "Plumber",
"@id": "https://example.com/#business",
"name": "Acme Plumbing",
"url": "https://example.com",
"telephone": "+1-561-555-0142",
"email": "hello@example.com",
"image": "https://example.com/storefront.jpg",
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "Jupiter",
"addressRegion": "FL",
"postalCode": "33458",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 26.9342,
"longitude": -80.0942
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "08:00",
"closes": "17:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": "Saturday",
"opens": "09:00",
"closes": "13:00"
}
],
"areaServed": [
{ "@type": "City", "name": "Jupiter" },
{ "@type": "City", "name": "Tequesta" },
{ "@type": "City", "name": "Palm Beach Gardens" }
],
"sameAs": [
"https://www.facebook.com/acmeplumbing",
"https://www.instagram.com/acmeplumbing"
]
}
A note on “required” versus “recommended”: Schema.org itself does not formally tag properties as required. Google’s structured-data documentation treats name, address, and telephone as required for LocalBusiness rich results, with geo, openingHoursSpecification, image, url, and priceRange strongly recommended. The @id is what lets every other schema on the site point back here without duplicating the whole block.
Common gotchas. The phone number must be in international format with the country code. priceRange is a string, not a number, and Google reads $, $$, $$$, $$$$ as real signals. areaServed should be cities you actually serve, not a fishing list of every nearby zip code. Google rewards accurate service areas and ignores obvious spam.
2. Service schema with provider and offer catalog
Each service you sell deserves its own page and its own Service schema. The provider points back to the LocalBusiness @id so Google knows the same business runs it.
{
"@context": "https://schema.org",
"@type": "Service",
"@id": "https://example.com/services/water-heater-installation/#service",
"name": "Water Heater Installation",
"serviceType": "Water heater installation and replacement",
"provider": { "@id": "https://example.com/#business" },
"areaServed": [
{ "@type": "City", "name": "Jupiter" },
{ "@type": "City", "name": "Tequesta" }
],
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Water heater services",
"itemListElement": [
{
"@type": "Offer",
"itemOffered": { "@type": "Service", "name": "Tank water heater install" },
"price": "1850.00",
"priceCurrency": "USD"
},
{
"@type": "Offer",
"itemOffered": { "@type": "Service", "name": "Tankless water heater install" },
"price": "3200.00",
"priceCurrency": "USD"
}
]
}
}
Don’t list prices you can’t honor. If your prices vary, drop hasOfferCatalog entirely and just describe serviceType. Google penalizes inconsistency between schema and page content faster than it rewards completeness.
3. FAQPage schema, when it actually applies
Quick reality check on FAQPage in 2026. Google scaled back FAQ rich results in August 2023 and continued tightening the eligibility through 2026, with rich-result rendering now restricted to a small slice of authoritative gov and health sites. For a service business, FAQPage is no longer a Google rich-result play. The reason to ship it is AI search: Perplexity and ChatGPT read FAQ schema heavily for citation, and well-structured question-and-answer blocks get surfaced for long-tail question variants in those engines even when Google itself does not render the rich result. The schema itself is straightforward.
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Do you offer same-day service?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. Calls placed before 11am Monday through Friday are scheduled the same day in our standard service area."
}
},
{
"@type": "Question",
"name": "What payment methods do you accept?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Visa, Mastercard, AmEx, ACH, and check. Net-15 invoicing available for commercial accounts."
}
}
]
}
Hard rules. The questions and answers in the schema must match the visible page text exactly. Don’t include a question in schema that isn’t shown to users. Don’t truncate. AI search engines like Perplexity and ChatGPT read FAQ schema heavily for citation, so concrete answers with real numbers earn citations.
4. BreadcrumbList for nested service pages
If your URL structure is /services/plumbing/water-heater-installation/, ship breadcrumb schema. It gives Google a clean hierarchy and improves SERP appearance.
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://example.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "Services",
"item": "https://example.com/services"
},
{
"@type": "ListItem",
"position": 3,
"name": "Water Heater Installation",
"item": "https://example.com/services/water-heater-installation"
}
]
}
The item field on the last breadcrumb is technically optional per the Schema.org spec, but Google’s Rich Results Test will warn if you omit it. Include it.
5. Person schema for the founder bio
If you want your founder to show up in Knowledge Panel results and AI search citations, ship a Person schema on the about page.
{
"@context": "https://schema.org",
"@type": "Person",
"@id": "https://example.com/about/#founder",
"name": "Chase Weiser",
"jobTitle": "Founder",
"worksFor": { "@id": "https://example.com/#business" },
"url": "https://example.com/about",
"image": "https://example.com/chase-weiser.jpg",
"sameAs": [
"https://www.linkedin.com/in/chaseweiser",
"https://github.com/chaseweiser"
]
}
sameAs is the field that earns Knowledge Graph entity recognition. List the profiles that establish the person’s identity across the web: LinkedIn, GitHub, Crunchbase, published author bylines. Don’t pad it with social profiles that have ten followers.
When @graph matters and when it doesn’t
If a page only has one schema type, just emit a single JSON-LD object. If it has three or more (LocalBusiness + Service + Breadcrumb is the typical service-page combo), use @graph so the relationships are explicit.
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "LocalBusiness", "@id": "https://example.com/#business", "name": "Acme Plumbing" },
{ "@type": "Service", "@id": "https://example.com/services/install/#service", "provider": { "@id": "https://example.com/#business" } },
{ "@type": "BreadcrumbList", "itemListElement": [] }
]
}
The @id references inside @graph connect the nodes without duplication. Google parses this correctly and so does every modern AI crawler.
What to do next
Validate every page through both tools, fix every error, address every warning unless you have a reason not to, then re-crawl through Search Console URL Inspection. Schema is one of the cheapest rich-result wins available, and most local business sites are still missing it. If you want a hand auditing your existing structured data and the rest of your local search footprint, that’s exactly what our SEO engagement starts with.
