All guides

schema markup

Schema markup examples that validate, and the three ways they usually break

Working JSON-LD for Article, FAQ, Product, Organization, Breadcrumb and LocalBusiness, plus the three failures that make schema silently ignored.

Table of the three ways schema breaks: one trailing comma or smart quote drops the whole block, markup the page does not show is a policy problem, schema injected by JavaScript is invisible to fetchers

Most schema tutorials give you a snippet and stop. The snippet is the easy part. What follows is a set of blocks that parse, plus the three failure modes that account for nearly every case where somebody has schema on the page and it is doing nothing.

Every example below is minimal on purpose. Adding properties you cannot fill honestly is how schema turns into a liability.

Article

The one most sites need and the one most often incomplete. datePublished and author are the two properties worth caring about, because they are the two that a machine trying to judge whether your page is trustworthy will look for first.

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Schema markup examples that validate",
  "description": "Working JSON-LD for the types most sites need.",
  "datePublished": "2026-08-14",
  "dateModified": "2026-08-14",
  "url": "https://example.com/blog/schema-markup-examples/",
  "author": {
    "@type": "Person",
    "name": "Jordan Ellis",
    "url": "https://example.com/about/"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Example Co",
    "url": "https://example.com/"
  }
}

Keep headline under about 110 characters, which is what Google’s Article structured data reference recommends. Keep dateModified honest: bumping it on a page you did not change is a pattern that is easy to detect and gains nothing.

Those two properties are also the two most often missing entirely. When we ran our own audit across professional marketing sites, no machine readable date failed on roughly a third of them and no author on a quarter, which puts this block near the top of the tips worth acting on first.

FAQPage

Read this before you add it, because the reason to has changed. Google deprecated the FAQ rich result on 7 May 2026, and removed the documentation page for it in June 2026; the old URL now redirects to the changelog entry recording the removal. If you were adding FAQPage for the accordion in the results page, that accordion is gone and no amount of correct markup brings it back.

It is still worth shipping, for the other reason. A marked up question and answer pair is the most extractable shape a page can contain, and extraction is what decides whether an assistant can lift a clean passage out of your page and attribute it. We publish it on every article here, including this one, on that basis rather than on a rich result we know we will not get. Answers must be plain text. An anchor tag inside text is markup in a field that is not markup.

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is schema markup?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "A vocabulary for describing what a page is about in a form a machine can parse."
      }
    },
    {
      "@type": "Question",
      "name": "Does it improve rankings?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Not directly. It makes rich results possible and removes ambiguity about what the page is."
      }
    }
  ]
}

The rule that keeps this legitimate: the questions and answers have to be visible on the page. Marking up questions a visitor cannot see is the single most common cause of a manual action against structured data, and Google’s structured data general guidelines say so in as many words.

Organization

The block that decides whether anything can resolve who you are as an entity rather than as a collection of pages. That distinction is the whole of AI visibility in one property: a page can rank without anything knowing who published it, and an assistant asked to recommend a company cannot name one it cannot resolve. sameAs is the important part and it is the one most often left out, because it is how a parser connects this site to the same company on other platforms.

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "@id": "https://example.com/#organization",
  "name": "Example Co",
  "url": "https://example.com/",
  "logo": "https://example.com/logo.png",
  "description": "One sentence saying what this company actually does.",
  "sameAs": [
    "https://www.linkedin.com/company/example",
    "https://x.com/example",
    "https://github.com/example"
  ]
}

Only list profiles that exist and that are genuinely yours. A sameAs pointing at a dead handle is worse than an absent one, because it asserts a connection that does not resolve.

Cheap, mechanical, and it tells a parser where the page sits in your hierarchy. position starts at 1 and must be contiguous.

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
    { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog/" },
    { "@type": "ListItem", "position": 3, "name": "Schema markup examples" }
  ]
}

The last item carries no item URL, because it is the page you are already on.

Product

The type with the most rules attached, because it is the one with the most incentive to lie. Price and availability must match what the page shows at the moment it is served.

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Example Widget",
  "description": "What the product is, in one honest sentence.",
  "image": "https://example.com/widget.jpg",
  "sku": "WIDGET-001",
  "brand": { "@type": "Brand", "name": "Example Co" },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/widget/",
    "price": "49.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock"
  }
}

Leave aggregateRating out unless you display real reviews on that page. Inventing it is the fastest route to losing rich results across the whole site rather than on the one page.

LocalBusiness

For anywhere with a physical presence. The address has to be structured rather than a single string, and the opening hours format is stricter than it looks.

{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Example Cafe",
  "url": "https://example.com/",
  "telephone": "+1-555-0100",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "12 Example Street",
    "addressLocality": "Portland",
    "addressRegion": "OR",
    "postalCode": "97201",
    "addressCountry": "US"
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "08:00",
      "closes": "17:00"
    }
  ]
}

The three ways schema actually breaks

Having audited a lot of live pages, the failures are not exotic. They are these, in this order.

It does not parse, so all of it is discarded. This is the one people underestimate. A malformed JSON-LD block is not partially read: a trailing comma, a smart quote pasted in from a document, or an unescaped quote inside a string, and the entire block is dropped without a warning anywhere. Nothing on the page tells you, and it looks correct in the source. Across the sites we have measured, structured data that is absent or fails to parse is one of the more common findings, and a meaningful share of it is markup somebody wrote, shipped and assumed was working.

It describes something the page does not show. A rating with no reviews on the page, a price the page does not display, an FAQ block whose questions appear nowhere. This is not a technical failure, it validates fine, and it is the one with an actual penalty attached.

It is injected by JavaScript. The block exists in the rendered DOM and is absent from the HTML that gets served. Anything that reads your page without running scripts, which is a large and growing set of things, sees no structured data at all. Put it in the served HTML. We wrote up the wider version of this failure in why AI crawlers see a blank page on your React site, where the same cause takes out the whole document rather than one script tag, and the render gap checker shows you the difference between the two on a live URL.

What schema will not do for you

Worth saying plainly, because a lot of advice implies otherwise. Google’s own guide to optimizing for generative AI search, published May 2026, puts structured data in its list of things people over-focus on: it is not required for generative AI features and there is no special markup that gets you into them. What it says structured data is still good for is the ordinary reason, which is rich result eligibility on classic Search.

That is consistent with what we measure and it is worth holding both halves. Schema does not make an assistant like you. It removes ambiguity about what your page and your organisation are, which is a floor rather than a lever, and floors are only visible when they are missing.

How to check yours

Fetch the page the way a crawler does, pull out every application/ld+json block, confirm each parses, then read what it claims and compare it against the visible page. The first two are mechanical and our structured data checker does them on a live URL. The third is a judgement and takes thirty seconds of reading.

Google’s Rich Results Test answers a narrower question, which is whether a specific rich result is available to you, and the Schema Markup Validator answers a broader one, which is whether the vocabulary is used correctly at all. A page can pass either and still be wrong in the way that matters, because neither of them knows what your page displays.

Do that once per template rather than once per page. Schema is generated by templates, so its failures are template shaped, and finding one broken block usually means finding several hundred broken pages. If you want the JSON-LD written for you from a page you describe rather than checked after the fact, the schema markup prompt does that, and the rest of the technical order of operations is in the technical SEO checklist.

Sources

Read on 15 August 2026. Check these rather than us: the vocabulary is stable and Google’s treatment of it is not.

Questions people ask

What is schema markup?

A vocabulary for describing what a page is about in a form a machine can parse, rather than leaving it to infer from prose. It is written as JSON-LD in a script tag and it does not change what a visitor sees. Its job is to remove ambiguity: this string is the author, this one is the price, this date is when it was published.

What is the difference between schema markup and JSON-LD?

Schema.org is the vocabulary, the set of types and properties. JSON-LD is one of three syntaxes for expressing it, alongside microdata and RDFa. JSON-LD is the one to use: it sits in a single script tag separate from your markup, so it does not entangle with your templates and it can be generated independently of how the page is rendered.

Does schema markup improve rankings?

Not directly, and that is the wrong reason to add it. It makes eligibility for rich results possible, and it removes ambiguity for anything trying to work out what your page and your organisation are. That second job has become the more valuable one, because assistants resolving who a company is read structured data before they read prose.

Where do I put schema markup on the page?

In a script tag with type application/ld+json, anywhere in the head or the body. Placement makes no difference to parsers. What does matter is that it is present in the HTML that gets served, not injected later by JavaScript, because plenty of things that read your page never run scripts.

Why is my schema markup not working?

Almost always one of three things: it does not parse as JSON, so it is discarded in full and silently; it describes something the page does not actually show, which is a policy problem rather than a technical one; or it is injected by JavaScript and the fetcher never ran the JavaScript. Validate it, then read it back against the visible page.

How do I test my schema markup?

Fetch the page as a crawler would, extract the JSON-LD blocks and check each one parses, then compare what it claims against what the page displays. Our structured data checker does exactly this on a live URL. Google's Rich Results Test answers a narrower question, which is whether you are eligible for a specific rich result, and a page can pass one and fail the other.

Related guides

Run your first audit
in about a minute

Free account, no card. Paste your URL and get a real, scored report of your AI and search visibility.

Measuring rankings in