Schema markup is one of the highest-leverage 30 minutes of work in local SEO. It tells Google explicitly what you are, where you are, and what you do, so it doesn't have to guess. Most service-business sites have zero structured data. Theirs is a guess. Yours doesn't have to be. These are the four templates we add to every Tampa client we onboard.
You add JSON-LD schema by pasting it inside the <head> of your page (or via a plugin if you use WordPress). Google's Rich Results Test (search.google.com/test/rich-results) lets you validate any of these templates after you paste them in. Validate before you ship.
1. LocalBusiness schema (homepage)
This is the foundation. Every local business site should have this on the homepage at minimum.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"@id": "https://yourbusiness.com/#localbusiness",
"name": "Acme Roofing",
"image": "https://yourbusiness.com/storefront.jpg",
"url": "https://yourbusiness.com",
"telephone": "+1-813-555-0100",
"email": "info@yourbusiness.com",
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main Street",
"addressLocality": "Tampa",
"addressRegion": "FL",
"postalCode": "33602",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": "27.9506",
"longitude": "-82.4572"
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "08:00",
"closes": "18:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": "Saturday",
"opens": "09:00",
"closes": "14:00"
}
],
"sameAs": [
"https://www.facebook.com/yourbusiness",
"https://www.instagram.com/yourbusiness",
"https://www.yelp.com/biz/yourbusiness-tampa"
],
"areaServed": [
{"@type": "City", "name": "Tampa"},
{"@type": "City", "name": "St. Petersburg"},
{"@type": "City", "name": "Clearwater"}
],
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.9",
"reviewCount": "127"
}
}
</script> What to customize:
@type— Use a more specific subtype if it fits:Plumber,Dentist,RoofingContractor,LegalService,Restaurant, etc. The more specific, the better Google's matching.aggregateRating— only include if you have real reviews. Google's structured data guidelines penalize fake or unsubstantiated ratings.openingHoursSpecification— match your GBP exactly. Mismatches between schema and GBP cause Google to ignore both.geo— find your coordinates at maps.google.com (right-click your address → coordinates copy to clipboard).
2. Service schema (one per service page)
Every service page should declare what service it covers. This unlocks rich results for service-specific queries.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "Roof Replacement",
"provider": {
"@type": "LocalBusiness",
"@id": "https://yourbusiness.com/#localbusiness",
"name": "Acme Roofing"
},
"areaServed": {
"@type": "City",
"name": "Tampa"
},
"description": "Full roof replacement for residential and commercial properties in Tampa, FL. Asphalt shingles, metal, and tile. 50-year manufacturer warranty.",
"offers": {
"@type": "Offer",
"priceSpecification": {
"@type": "PriceSpecification",
"priceCurrency": "USD",
"price": "8000",
"valueAddedTaxIncluded": "false",
"description": "Starting price; actual quote depends on roof size and material."
}
}
}
</script> Note on pricing: if you list a starting price, make it accurate. Google's helpful content guidelines explicitly call out misleading pricing. If you don't want to commit to a number, leave the offers object out — the rest of the schema is still valuable.
3. FAQ schema (page sections with Q&A)
Every blog post and service page should have an FAQ section. Wrapping it in FAQ schema can produce rich results in search and is one of the fastest-deploying structured-data wins.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How long does a tile roof last in Florida?",
"acceptedAnswer": {
"@type": "Answer",
"text": "A properly installed tile roof in Florida typically lasts 40-50 years. Coastal humidity and salt air shorten lifespan slightly compared to inland Florida; expect 35-45 years if you're within 5 miles of the coast."
}
},
{
"@type": "Question",
"name": "Do you offer financing?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. We work with three lenders to offer financing terms from 12 to 120 months. Most homeowners qualify with credit scores above 640."
}
},
{
"@type": "Question",
"name": "What's your response time for storm damage?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Within 24 hours for emergency tarp-and-secure work, within 7 days for full damage assessment and repair quote. We prioritize jobs by safety risk."
}
}
]
}
</script> Important: the questions and answers in your FAQ schema must match the visible content on your page. Google penalizes hidden FAQ schema that doesn't appear in the rendered HTML.
4. BreadcrumbList schema (navigation hierarchy)
Tells Google how your page sits in the site's hierarchy. Essential for blog posts and deep service pages. Helps with rich-result breadcrumb display in search results.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://yourbusiness.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "Services",
"item": "https://yourbusiness.com/services"
},
{
"@type": "ListItem",
"position": 3,
"name": "Roof Replacement",
"item": "https://yourbusiness.com/services/roof-replacement"
}
]
}
</script> Common mistakes to avoid
1. Schema that doesn't match visible content.
If your homepage says "open 8–6 weekdays" but your schema says "open 24/7," Google ignores both. Keep schema and visible content in sync.
2. AggregateRating without real reviews.
You can't invent a 4.9 rating. Google has a manual penalty specifically for this. Either pull live data from your GBP or omit the field.
3. Multiple LocalBusiness blocks on the same page.
One per page maximum. Multiple causes Google to ignore all of them.
4. Forgetting to update schema after a move.
If you change your address, phone, or hours, update schema the same day. Stale schema is worse than no schema.
5. Not validating before deploying.
Run every schema block through Google's Rich Results Test (search.google.com/test/rich-results) before you ship it. Two minutes of work that catches 90% of errors.
How to deploy
WordPress: use Rank Math or Yoast SEO. Both let you add LocalBusiness schema globally and per-page schema on individual pages.
Astro / Next.js / static sites: paste directly into your layout's <head>. For per-page schema (like FAQ on a blog post), pass schema as a prop and inject conditionally. See our GBP optimization guide for context on where these fit in the broader SEO setup.
Shopify / Wix / Squarespace: these usually have built-in schema fields, but they're often incomplete. Check what they emit (View Source, Ctrl-F for "ld+json"). If fields are missing, add custom schema via the platform's <head> injection (most have one in advanced settings).
What schema doesn't do
Schema markup doesn't directly rank you. It tells Google what you are. Whether you rank still depends on the underlying signals — citations, reviews, content, link authority, GBP optimization. Schema is a multiplier, not a standalone lever. Don't expect a homepage with thin content and 14 schema blocks to outrank a strong site with one schema block.
That said, the work-to-impact ratio is excellent. Twenty minutes of paste-and-validate often produces visible rich-result lifts within 30 days. Few SEO tasks are that cheap.
FAQ
Do I need schema markup if I have a Google Business Profile?
Yes. GBP and on-site schema are different surfaces. GBP feeds the Map Pack and Knowledge Panel; on-site schema feeds organic search results, rich snippets, and AI Overviews. You want both.
Can schema markup hurt my SEO if I do it wrong?
Yes — but only in specific ways. Spammy schema (fake reviews, hidden FAQ content) gets manual penalties. Mismatched schema (says open at 8 AM but page says 9 AM) causes Google to ignore the schema, which is the same as not having it. Empty or broken schema is harmless.
What's the difference between Microdata, RDFa, and JSON-LD?
All three are structured-data formats. JSON-LD is what Google recommends and what every modern stack should use. It lives in a <script> tag in the head, separated from your visible markup. Microdata and RDFa embed inside HTML elements; both are still valid but more error-prone and harder to maintain.
Should I add Review schema for individual reviews?
Only if those reviews are real and on your own site. Don't pull star ratings from third-party sites and reproduce them as Review schema — that's the surest way to a manual penalty.
How do I check if my schema is working?
Three steps. (1) Run the page through Google's Rich Results Test. (2) Submit the page to Google Search Console and watch the Enhancements section for FAQ, Review, or Sitelinks displays over 30 days. (3) Search your business name and look at the Knowledge Panel — it should show data from your schema once Google has crawled and indexed.
Want a free schema audit on your homepage?
We'll run your site through the Rich Results Test, tell you what's missing, and give you the exact JSON to paste in. Tampa area service businesses only.
Get my free audit →