
Schema markup tells Google's AI exactly what your business is, what it offers, and where it's located. Most small businesses skip it entirely, which is why it's one of the highest-leverage local SEO opportunities available right now.
Schema markup is the fastest technical SEO win most local businesses never touch. Add the right structured data to your website and Google can display your hours, address, star ratings, and service areas directly in search results, before anyone clicks. This guide covers exactly what to implement, how to write the JSON-LD code, and where most businesses get it wrong.
Schema markup is code you add to your website that tells search engines what your content means, not just what it says. Without it, Google has to guess that "9am–5pm Mon–Fri" refers to your business hours. With LocalBusiness schema, that relationship is explicit.
The payoff for local businesses: rich results. These are the enhanced search listings that show star ratings, hours, address, and price range directly in the search snippet. Rich results get significantly higher click-through rates than plain blue links, studies consistently show 20-30% CTR improvements for businesses with structured data vs. those without.
Schema markup also feeds the data layer that powers Google Maps, voice search, and increasingly, AI Overviews. When Google's AI summarizes "best HVAC company near me," it's pulling from structured signals, businesses with clean schema markup are more likely to be cited.
💡 Pro Tip: Schema markup is not a ranking factor in the traditional sense, it won't move you from position 8 to position 1. What it does is dramatically improve how your result looks and performs once you rank. The click-through rate improvement from rich results is often worth more than a 2-3 position ranking gain.
The LocalBusiness schema type is the foundation. Every local business website should have it. Here are the properties that matter:
Required (Google will ignore your markup without these):
@type, the business type (see full type list below)name, exact legal business name, matching your GBPaddress, structured using PostalAddress subtypetelephone, primary contact numberStrongly recommended (appear in rich results):
openingHoursSpecification, structured hours by daygeo, latitude/longitude coordinatesurl, your website URLimage, at least one high-quality photo URLaggregateRating, average rating and review count (pulls from review data)priceRange, dollar signs ($, $$, $$$)Optional but valuable:
sameAs, links to your GBP, Yelp, Facebook, and other profilesserviceArea, geographic area you serve (critical for service area businesses)hasMap, link to your Google Maps listingdescription, brief business description⚠️ Common Mistake: Using
Organizationschema instead ofLocalBusiness. Organization schema is for companies without a physical location or service area focus. If you have a street address or serve customers in a specific geographic area,LocalBusiness(or a more specific subtype) is correct.
The best practice for implementing schema is JSON-LD (JavaScript Object Notation for Linked Data) injected in the <head> of your page. It keeps the schema separate from your HTML and is Google's preferred format.
Named Framework: The Local Schema Stack
Layer 1, LocalBusiness core (required for all) Layer 2, Business-type subtype (specificity boost) Layer 3, Advanced types: FAQPage, Service, Event (rich result triggers)
Template: Restaurant
{
"@context": "https://schema.org",
"@type": "Restaurant",
"name": "The Corner Bistro",
"address": {
"@type": "PostalAddress",
"streetAddress": "142 Oak Street",
"addressLocality": "Austin",
"addressRegion": "TX",
"postalCode": "78701",
"addressCountry": "US"
},
"telephone": "+1-512-555-0192",
"url": "https://www.thecornerbistro.com",
"image": "https://www.thecornerbistro.com/images/exterior.jpg",
"priceRange": "$$",
"servesCuisine": "American",
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "11:00",
"closes": "22:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Saturday", "Sunday"],
"opens": "10:00",
"closes": "23:00"
}
],
"geo": {
"@type": "GeoCoordinates",
"latitude": 30.2672,
"longitude": -97.7431
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"reviewCount": "312"
},
"sameAs": [
"https://www.google.com/maps/place/...",
"https://www.yelp.com/biz/corner-bistro-austin"
]
}
Template: Service Area Business (no storefront)
{
"@context": "https://schema.org",
"@type": "Plumber",
"name": "Austin Fast Plumbing",
"telephone": "+1-512-555-0144",
"url": "https://www.austinfastplumbing.com",
"image": "https://www.austinfastplumbing.com/logo.jpg",
"areaServed": {
"@type": "City",
"name": "Austin"
},
"serviceArea": {
"@type": "GeoCircle",
"geoMidpoint": {
"@type": "GeoCoordinates",
"latitude": 30.2672,
"longitude": -97.7431
},
"geoRadius": "50000"
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
"opens": "00:00",
"closes": "23:59"
}
]
}
🔥 Quick Win: Get your latitude and longitude from Google Maps: right-click your business location on the map, click "What's here?" and copy the coordinates shown at the bottom. Drop them directly into your
GeoCoordinatesblock.
LocalBusiness subtypes worth knowing:
| Business Type | Schema Subtype |
|---|---|
| Restaurant / cafe | Restaurant, CafeOrCoffeeShop, FastFoodRestaurant |
| Medical / dental | MedicalBusiness, Dentist, Physician |
| Legal | LegalService, Attorney |
| Home services | Plumber, Electrician, HVACBusiness, RoofingContractor |
| Automotive | AutoRepair, AutoDealer |
| Fitness | SportsActivityLocation, HealthClub |
| Beauty | HairSalon, NailSalon, BeautySalon |
| Retail | Store, ClothingStore, JewelryStore, FurnitureStore |
| Hotel / lodging | Hotel, LodgingBusiness, Motel |
Using the correct subtype instead of the generic LocalBusiness gives Google more precision about what your business does and can unlock category-specific rich result formats.
Most local businesses stop at LocalBusiness. The ones that rank consistently add these:
FAQPage Schema
If your page has a FAQ section, wrap it in FAQPage schema. This can trigger accordion-style rich results that take up significantly more SERP real estate.
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Do you offer emergency plumbing services?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. We offer 24/7 emergency plumbing services in Austin and surrounding areas. Call 512-555-0144 for immediate response."
}
},
{
"@type": "Question",
"name": "What areas do you serve?",
"acceptedAnswer": {
"@type": "Answer",
"text": "We serve Austin, Round Rock, Cedar Park, Pflugerville, and all Travis County communities within 50 miles of downtown Austin."
}
}
]
}
Service Schema
Add individual Service entries for your key offerings. This creates machine-readable service data that Google uses for service-specific searches.
{
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "Drain Cleaning",
"provider": {
"@type": "Plumber",
"name": "Austin Fast Plumbing"
},
"areaServed": {
"@type": "City",
"name": "Austin"
},
"description": "Professional drain cleaning using hydro-jetting and camera inspection for Austin homes and businesses."
}
BreadcrumbList Schema
Adds breadcrumb navigation links to your search snippet. Small visual upgrade, but every SERP enhancement improves CTR.
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://www.austinfastplumbing.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "Services",
"item": "https://www.austinfastplumbing.com/services"
},
{
"@type": "ListItem",
"position": 3,
"name": "Drain Cleaning",
"item": "https://www.austinfastplumbing.com/services/drain-cleaning"
}
]
}
📊 Flento Data: Flento's analysis of local business websites with active schema markup shows that businesses using 3 or more schema types (LocalBusiness + FAQPage + Service) generate 2.8x more organic clicks per impression than businesses using only basic LocalBusiness schema.
Multi-location businesses: Create a separate LocalBusiness schema block for each location. Do not try to combine multiple locations into one schema entry. Each location page on your website should have its own schema referencing that specific location's NAP.
{
"@context": "https://schema.org",
"@type": "Restaurant",
"name": "The Corner Bistro - South Congress",
"address": {
"@type": "PostalAddress",
"streetAddress": "1842 South Congress Ave",
"addressLocality": "Austin",
"addressRegion": "TX",
"postalCode": "78704"
}
}
Seasonal or holiday hours: Use OpeningHoursSpecification with validFrom and validThrough dates for temporary schedule changes.
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Saturday", "Sunday"],
"opens": "09:00",
"closes": "14:00",
"validFrom": "2026-11-25",
"validThrough": "2026-12-26"
}
⚠️ Common Mistake: Leaving outdated holiday hours in your schema long after the holiday has passed. Set a calendar reminder when you add seasonal hours to remove or update the
validThroughdate.
Google's AI Overviews and voice search assistants both rely heavily on structured data to generate accurate local business information. When Google's AI answers "what are the best dentists near me open on Saturday," it pulls from:
Businesses with clean, complete schema markup are more likely to be included in AI-generated responses because the data is machine-readable without interpretation. Voice search specifically needs structured hours, phone numbers, and service area data, these aren't reliably extracted from unstructured text.
For AI visibility, prioritize:
openingHoursSpecification with every day of the week specifiedtelephone in international format (+1-512-555-0144, not 512.555.0144)serviceArea or areaServed for service area businessesFAQPage schema matching the questions your customers actually ask💡 Pro Tip: Write your FAQ schema answers the way you'd answer a voice search question, complete sentences, specific geographic references, and no jargon. "We serve Austin, Texas and surrounding communities within 30 miles" beats "Austin metro area" for voice search matching.
Google's Rich Results Test (search.google.com/test/rich-results): Paste your URL or code and see exactly which rich results Google detects and whether there are errors. Run this immediately after implementing schema and again every time you change your website.
Google Search Console, Enhancements report: After your schema is indexed, GSC shows rich result performance, how many impressions and clicks your structured data is generating. Find it under Search Console > Search Appearance > Rich Results.
Schema Markup Validator (validator.schema.org): Validates your JSON-LD against the schema.org specification. Catches syntax errors that Google's tool might not flag.
Common errors to check:
telephone not in international format, should start with +1 for US numbersopeningHoursSpecification missing days, if you're closed Monday, still list it with opens: "00:00" and closes: "00:00" rather than omitting itaggregateRating with fabricated or outdated numbers, only use real review counts; Google cross-references thesenoindex or robots.txt, schema is invisible if Google can't crawl the page@type values, if you're a Dentist, don't also declare Organization on the same page🛠️ Action Step: Go to
search.google.com/test/rich-resultsright now. Enter your homepage URL. If you see "No items detected" or error warnings, your schema isn't working and this guide gives you exactly what to fix.
WordPress: The Rank Math or Yoast SEO plugins generate LocalBusiness schema automatically from your settings. Fill in your business name, address, phone, hours, and the plugin writes the JSON-LD. No code required.
Shopify/Squarespace/Wix: These platforms have built-in schema for product and business pages, but coverage is incomplete. Use Google Tag Manager to inject a custom JSON-LD block across your site without touching the platform's code.
Google Tag Manager (any platform): Create a new tag, select "Custom HTML," paste your JSON-LD wrapped in <script type="application/ld+json"> tags, and set it to fire on All Pages (or specific pages). This keeps your schema separate from your CMS and easy to update.
Manual implementation: Add the JSON-LD block inside <script type="application/ld+json"> tags in the <head> section of your HTML. If you're editing a template file, add it once and it applies site-wide.
Use this to verify your implementation is complete:
LocalBusiness schema (or specific subtype) on homepage and all location pages@type set to the most specific applicable subtype, not generic LocalBusinessname matches GBP exactlyaddress uses structured PostalAddress with all fieldstelephone in international format (+1-XXX-XXX-XXXX)openingHoursSpecification covers all 7 daysgeo coordinates added (latitude/longitude)image URL points to a real, accessible imagesameAs includes GBP, Yelp, and Facebook profile URLsFAQPage schema on pages with FAQ sectionsService schema for each core service offeringStart free →, Flento's local SEO platform monitors your schema health alongside your GBP, citations, and review signals from one dashboard.
What is local SEO schema markup? Local SEO schema markup is structured data code, specifically JSON-LD, added to a local business website that tells search engines the name, address, hours, phone number, services, and other details about the business in a machine-readable format. It enables rich results in Google search (star ratings, hours display, address in the snippet) and feeds the data layer used by Google Maps, voice search, and AI Overviews.
What schema type should a local business use?
Start with LocalBusiness schema, then use the most specific subtype that fits your business: Restaurant, Plumber, Dentist, AutoRepair, etc. The full list of subtypes is at schema.org/LocalBusiness. More specific types give Google more precision about what you do and can unlock category-specific rich result formats.
Does schema markup directly improve local rankings? Schema markup is not a direct local ranking factor. It improves how your listing appears in search results, triggering rich results that show star ratings, hours, and address, which increases click-through rates. Improved CTR can have an indirect positive effect on rankings over time. The primary value of schema is better visibility and more clicks from your existing ranking position.
How do I add schema markup to my website without coding?
WordPress users can use the Rank Math or Yoast SEO plugins, which generate LocalBusiness schema automatically. For any platform, Google Tag Manager lets you inject custom JSON-LD without editing your website code directly. The cleanest manual approach is adding a <script type="application/ld+json"> block to the <head> of your HTML template.
What is the difference between schema markup and Google Business Profile? Google Business Profile (GBP) is a separate platform managed through Google where you claim and update your business information. Schema markup is code on your own website. Both communicate business information to Google, but they're independent. GBP has more direct influence on Maps rankings; schema markup improves how your website ranks in organic search and how your listing displays in rich results. Having both, with consistent NAP data, is the strongest setup.
How do I know if my schema markup is working?
Test your URL with Google's Rich Results Test at search.google.com/test/rich-results. After a few weeks, check the Enhancements section in Google Search Console, it shows which rich result types Google has detected on your site and their impression/click performance. If schema is live and indexed but not generating rich results, check for errors in the Rich Results Test output.
What is schema markup for multiple business locations?
Multi-location businesses should create a separate LocalBusiness schema block for each location, placed on that location's dedicated page. Never combine multiple addresses into one schema entry. Each location page should have schema that references only that location's NAP, the same NAP that appears on that page's content and in your GBP listing for that location.