Open a search results page and look closely at the listings above and below the one you clicked. Some are plain: a blue title, a green URL, two lines of description. Others carry a star rating, a price range, a list of recipe ingredients, or a stack of expandable questions right there in the results. That difference isn't luck, and it isn't a paid placement. It's schema markup — code added to a page that tells search engines exactly what the content on it means, instead of leaving them to guess.

This guide covers which schema types are actually worth the effort for a small business site, working JSON-LD examples you can adapt, how to validate what you've added, and the mistakes that get sites a manual action instead of a rich result. It assumes the fundamentals from our SEO for Beginners guide are already in place — schema markup is a layer on top of good content, not a substitute for it. It also goes deeper than the single paragraph on structured data in our technical SEO audit checklist, which is a good place to start if you haven't audited the basics yet.

What schema markup actually is

Schema markup is a shared vocabulary — maintained at schema.org by Google, Microsoft, Yahoo, and Yandex jointly — for labeling the parts of a web page. Instead of a search engine inferring from surrounding text that a number is probably a price, schema markup states it directly: this is a Product, its name is X, its price is Y, its currency is USD. The labels remove ambiguity. Search engines still read and judge your actual content; schema just tells them, with certainty, what kind of content they're looking at.

It's worth being precise about what this buys you, because the marketing language around it oversells the effect. Schema markup is not a ranking factor — Google has said this directly, more than once. What it does is make certain rich results eligible: star ratings, FAQ dropdowns, breadcrumb trails, recipe details, event dates, and a handful of other enhanced formats in search results. A rich result doesn't move you from position 8 to position 2. It can, however, make position 2 visually larger and more clickable than the plain links around it — and a meaningfully higher click-through rate at the same position is a real, measurable gain.

JSON-LD, microdata, and why JSON-LD wins

Schema markup can be written in three formats: JSON-LD, Microdata, and RDFa. All three are understood by Google, but they're not equally practical to maintain.

  • Microdata and RDFa are written as attributes scattered directly inside your visible HTML tags (itemscope, itemprop, and similar). That means the markup is tightly coupled to your page layout — change the HTML structure and you risk silently breaking the schema.
  • JSON-LD is a single, self-contained block of JSON placed inside a <script type="application/ld+json"> tag, usually in the <head>. It doesn't touch your visible markup at all, which makes it far easier to add, edit, template, and generate programmatically without any risk of breaking the page's layout.

Google's own documentation and tooling are built around JSON-LD, and it's what this guide uses throughout. Unless you're working inside a legacy system that already uses microdata extensively, there's no good reason to choose anything else for new markup today.

Which schema types are actually worth implementing

Schema.org defines hundreds of types, and trying to use all of them is a waste of time — most don't apply to a typical small business site, and some only unlock a rich result for specific, high-authority sites (recipe markup with full nutrition data, for instance, mostly matters for large food publishers). For a small business site, a handful of types cover nearly every real opportunity:

Schema typeUse it forVisible result
ArticleBlog posts and guidesRicher preview in some contexts; required base for several other enhancements
LocalBusinessA physical location or service areaSupports knowledge panel details; pairs with your Google Business Profile
Product / OfferAnything sold directly with a pricePrice, availability, and rating shown directly in results
FAQPagePages genuinely structured as question-and-answerExpandable Q&A dropdown under the listing
Review / AggregateRatingGenuine customer reviews you collectedStar rating shown next to the listing
BreadcrumbListEvery page with a clear site hierarchyBreadcrumb trail shown instead of a raw URL path

Implement the types that genuinely match content you already have. Adding FAQPage markup to a page with no real questions, or Review markup for reviews that don't exist, is the single most common way this backfires — more on that below.

Article schema: a working example

Every guide or blog post on a content-driven site is a reasonable candidate for Article schema. It's also the foundation this guide's own page uses — the two JSON-LD blocks in this article's <head> are a live example, not just sample code. A minimal, honest version looks like this:

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Your Article's Full Title",
  "description": "The same description you wrote for your meta tag.",
  "author": {
    "@type": "Organization",
    "name": "Your Business Name"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Your Business Name",
    "logo": {
      "@type": "ImageObject",
      "url": "https://yourdomain.com/logo.png"
    }
  },
  "datePublished": "2026-10-11",
  "dateModified": "2026-10-11",
  "mainEntityOfPage": "https://yourdomain.com/your-article-url"
}

Keep the headline, description, and dates consistent with what's actually on the page and in your meta tags. Google cross-checks structured data against visible content, and markup that contradicts the page is treated as unreliable, not just unused.

LocalBusiness schema: a working example

If you serve customers from a physical location or defined service area, LocalBusiness schema reinforces the same facts you've already set up in your Google Business Profile — see our local SEO guide for that setup. The two should always say the same thing; mismatched hours or addresses between your Business Profile and your site's schema is a trust signal in the wrong direction.

{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Your Business Name",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "123 Main Street",
    "addressLocality": "Your City",
    "addressRegion": "Your Region",
    "postalCode": "00000",
    "addressCountry": "US"
  },
  "telephone": "+1-555-000-0000",
  "openingHours": "Mo-Fr 09:00-18:00",
  "url": "https://yourdomain.com"
}

For a business with multiple categories (a specific industry like a dental practice, a restaurant, or a legal service), schema.org defines more specific subtypes — Dentist, Restaurant, LegalService, and dozens of others — that inherit everything LocalBusiness offers plus a few category-specific fields. Use the most specific type that honestly fits.

Product schema: a working example

If you sell anything directly from your site, Product schema is usually the highest-value type to implement, because it's what makes price and availability visible in the results themselves — a meaningful pre-qualifier that can improve click quality, not just click volume.

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Product Name",
  "description": "Product description matching the page.",
  "offers": {
    "@type": "Offer",
    "priceCurrency": "USD",
    "price": "49.99",
    "availability": "https://schema.org/InStock",
    "url": "https://yourdomain.com/product-url"
  }
}

If you're on an established e-commerce platform (Shopify, WooCommerce, and most others), this is frequently generated automatically by the platform or a plugin — check before building it by hand, and audit what's already there rather than assuming it's correct.

FAQPage schema: a working example

FAQPage markup is one of the more visually prominent rich results — an expandable list of questions directly under your listing — and one of the most frequently misused. It's only appropriate for a page that genuinely presents a question-and-answer format, not a page where you've bolted three questions onto the bottom purely to chase the rich result.

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Exact question text as shown on the page",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The exact answer text as shown on the page."
      }
    }
  ]
}

Add one Question/Answer pair per FAQ item on the page, in the same order they appear. The text in the markup must match the visible text — this is one of the mismatches Google checks for specifically.

Review and AggregateRating schema — and the honesty rule

Review markup is the highest-risk type on this list because it's also the most commonly abused. The rule is simple and absolute: only mark up reviews that real customers actually left, through a review platform, your own collected testimonials, or a verified on-site review system. Never fabricate a rating, average several unrelated mentions into a number, or mark up a testimonial as a formal "review" if it wasn't collected as one. Google's structured data guidelines explicitly list fake or self-serving review markup as grounds for a manual action — not a warning, an actual penalty that can suppress the whole site's rich results or rankings.

If you have genuine collected reviews, AggregateRating schema (nested inside a Product or LocalBusiness block) is the standard approach:

"aggregateRating": {
  "@type": "AggregateRating",
  "ratingValue": "4.7",
  "reviewCount": "38"
}

That number must be the real, current average from your actual review count — not a rounded-up figure, and not one that stops updating once it looks good.

This is the lowest-risk, highest-consistency type to roll out sitewide, because it just restates your existing site navigation in machine-readable form — there's no honesty judgment call involved, it's purely structural. The two JSON-LD blocks at the top of this very page are a working example: an Article block and a BreadcrumbList block, each handling one job. Every page on a site with a clear hierarchy (home → category → page) is a reasonable candidate for this markup.

How to implement schema markup, step by step

  1. Decide which types genuinely match your content. Walk through the table above and only pick types for content that actually exists — don't manufacture FAQs or reviews to qualify.
  2. Check if your CMS or platform already generates it. WordPress SEO plugins, Shopify, and most modern site builders generate Article, Product, or LocalBusiness schema automatically. View your page source and search for application/ld+json before writing anything by hand.
  3. Write the JSON-LD block, using the examples above as templates, with every value matching the actual visible content on the page.
  4. Place it inside the page's <head> as a <script type="application/ld+json"> tag, one block per schema type, exactly as shown in this article's own source.
  5. Validate it before publishing, using the tools covered next.
  6. Re-check after any content update. If a price, FAQ answer, or review count changes on the page, the matching schema values need to change with it.

Testing and validating your markup

Two free tools cover this completely:

  • Google's Rich Results Test (search.google.com/test/rich-results) checks whether a URL's structured data is eligible for a specific rich result and flags syntax errors or missing required fields.
  • Schema.org's own Validator (validator.schema.org) checks pure spec compliance even for types that don't have a dedicated Google rich result, which is useful for catching malformed JSON before it reaches a live page.

Run every new or changed schema block through the Rich Results Test before publishing, not after. A validation error caught before launch takes thirty seconds to fix; the same error caught weeks later after it's suppressed a rich result sitewide takes much longer to notice and diagnose.

Common mistakes that cost more than they help

  • Markup that contradicts the visible page. A price, date, or FAQ answer in the schema that doesn't match what a visitor actually sees is treated as spam, not an oversight.
  • Fabricated or inflated reviews. Covered above — this is the mistake most likely to trigger an actual manual action rather than just a missed rich result.
  • Marking up content that isn't really there. FAQPage schema on a page with no real Q&A section, or Event schema for something that isn't a scheduled event, gets ignored at best and penalized at worst.
  • Letting schema go stale. A Product block that still shows "InStock" for something that sold out weeks ago misleads searchers and erodes the trust that made the rich result worth having.
  • Over-marking a single page. Stacking five unrelated schema types onto one page to chase every possible rich result usually just produces conflicting signals. One or two accurate, well-matched types outperform five speculative ones.

Monitoring results in Search Console

Google Search Console's "Enhancements" section reports on each structured data type it has detected across your site — how many pages are valid, how many have warnings, and how many have outright errors, updated roughly weekly. This is where a real implementation problem shows up before it costs you a rich result at scale: a template error that breaks FAQPage markup across fifty pages will appear here as fifty pages with errors, long before you'd notice it by spot-checking individual URLs. Check this report after any sitewide template or CMS change, the same way you'd check Core Web Vitals after a redesign.

Conclusion

Schema markup is a small, mechanical addition with an outsized effect on how a listing looks in search results — but only when it's accurate. Pick the handful of types that genuinely match content you already have, write them as clean JSON-LD, validate every block before it goes live, and keep the values in sync as the underlying content changes. Skip the temptation to mark up reviews, FAQs, or ratings that don't really exist; that's the one mistake on this list that can cost you more than it was ever going to gain.