Content

Structured Data for SEO: JSON-LD, Eligibility, and What Google Actually Uses

How JSON-LD structured data makes pages eligible for Google rich results, which types are worth implementing, and why markup is not a ranking lever or an AI-visibility shortcut.

Valid structured data does not move a page up the rankings. This article covers which types are worth a ticket for ecommerce, publishing, marketplace, and SaaS sites, how Google's Search documentation relates to the schema.org vocabulary, and why FAQPage and HowTo are no longer Search features.

What structured data is

Structured data is a standardised format for providing information about a page and classifying the page content. Google Search uses it as explicit clues about meaning: which entity the page is about, and which properties belong to that entity.

Google already works hard to understand the content of a page without markup. For products, Google can take rich product data from on-page Product markup, from a Merchant Center feed, or both. Product snippets may even use pricing from the feed when it is missing from the page's structured data. Amazon is the classic example: product rich results appear for Amazon URLs that are not explained by a public JSON-LD implementation. That is not a reason to skip markup. Most sites are not Amazon, and JSON-LD is how you make the same extraction complete, current, and eligible for the documented Search features.

Most Search structured data uses the schema.org vocabulary, a shared set of types and properties for describing things on the web (a product, an organisation, an article). The format Google recommends is JSON-LD (JavaScript Object Notation for Linked Data): a <script type="application/ld+json"> block in the page that is not interleaved with visible HTML.

Markup labels content that is already on the page. It does not invent a feature, and it does not substitute for visible, accurate information.

Eligibility, appearance, and ranking are different things

Treat structured data as three layers, not one deliverable:

  1. Markup: you added syntactically valid structured data of a given type.
  2. Eligibility: the type is a current Google Search feature, required properties are present, the page is crawlable, and the general structured data guidelines are met.
  3. Appearance: Google may show a rich result (an enhanced search result such as product price, review stars, or a breadcrumb trail). Eligibility does not guarantee that it will.

Appearance is not a ranking factor. A page can rank in web search with no rich result, and a rich result can be withheld even when markup is valid. Google does not guarantee that features which consume structured data will show up.

A structured-data manual action (a penalty applied through Search Console's Manual Actions report) means the page loses eligibility to appear as a rich result. Google's general guidelines state that this does not affect how the page ranks in Google web search. Fix the markup and request a review; do not treat the action as a ranking crash, and do not treat clean markup as a ranking lift.

Schema markup enables Search features. It is not a ranking lever. That is also the position in Semantic Relevance: implement types that enable features you want; do not expect schema to substitute for comprehensive, well-structured content.

Google publishes case studies of sites that implemented structured data on the introduction page. Use those as Google's own illustrations, not as a performance claim for your site, and measure your own pages in Search Console rather than copying another site's outcome.

JSON-LD, Microdata, and RDFa

Google Search supports three formats unless a feature's documentation says otherwise:

Format How it is written Google's position
JSON-LD A JSON object in a script tag in head or body Recommended, because it is usually the easiest to implement and maintain
Microdata HTML attributes (itemscope, itemtype, itemprop) on visible elements Equally fine if valid
RDFa HTML5 attributes that correspond to visible content Equally fine if valid

Do not spend a sprint converting working Microdata to JSON-LD for Google's benefit. Convert if your stack makes JSON-LD cheaper to maintain, or if nested objects (an organisation with an address, an offer with a return policy) are painful in attributes.

Google can read JSON-LD that JavaScript injects into the DOM, including via Google Tag Manager, as documented in Generate structured data with JavaScript. Server-render it by default, especially for Product (Where the markup lives).

Google's documentation versus schema.org

schema.org is the vocabulary. Google Search Central is the specification for Google Search behaviour.

That distinction is how you scope the work. schema.org defines far more types and properties than Google documents for Search. Extra attributes "may be useful for other search engines, services, tools, and platforms," in Google's words. They are not a Google rich-result programme. If a type is absent from Google's search gallery, treat it as optional graph work: allocate time for it when nothing more impactful is waiting, not as a Search deliverable.

Google can make general use of sameAs and other schema.org structured data, and some of those elements may be used for future Search features. That is not a reason to mark up every type in the vocabulary "in case it helps later." Implement current, documented features that match the page.

The two also validate differently. Google's Rich Results Test only reports types Google uses for rich results, which is why it is named that. It will not acknowledge CollectionPage, Service, extra schema.org properties, or any other node that is not a current Search feature. The Schema Markup Validator checks the vocabulary itself, without Google-specific warnings. That pass is often stricter on types and properties Google never looks at, and it is not Search eligibility. A green Rich Results Test is not a schema.org pass, and a clean schema.org pass is not a Google rich result. Google documents both tools on the same testing page: start with the Rich Results Test for a Search ticket; use the schema.org validator when you are doing the optional graph work.

Which types are worth implementing

For ecommerce, publishing, marketplace, and SaaS sites, ticket the types below. Each one maps to a documented Google Search feature. Follow the feature guide for required and recommended properties; this article does not restate those property lists.

Type Typical pages Why it is worth a ticket
Product Product and offer pages, not service pages Product snippets and merchant listings (price, availability, ratings, shipping, returns). Trust-signal properties and a Product example are in E-E-A-T for product pages.
Organization Home page or About page Helps Google disambiguate the organisation; some properties influence the logo and knowledge panel. Merchants can attach return and shipping policy markup here. There are no required properties; add those that apply.
Article News, blog, and sports articles Helps Google present title, image, date, and author information. There is no markup requirement for Google News features such as Top stories.
Video Dedicated watch pages Video search features. Implementation, required properties, and hosting constraints are covered in Video SEO.
Breadcrumb Hierarchical category and detail pages Breadcrumb trails in results. Google documents this feature as available on desktop.
Review snippet Product pages and qualifying review pages Stars and rating summaries. Self-serving reviews of your own local business or organisation are ineligible for that star feature.

Product is for a product, not a service

schema.org's Product type includes services ("any offered product or service"). Google Search Product features do not. Ticket Product only on a page about a specific product a shopper can buy, or an editorial page about that product for product snippets. Merchant listings require a page where the shopper can purchase the product from you.

Do not put Product markup on a service page: consulting, maintenance, accounting, financial planning, streaming, or a SaaS plan that sells labour, time, or access rather than ownership of a product. That markup will not match the page, and it will not make the URL eligible for product snippets or merchant listings.

Merchant listing experiences follow Merchant Center policy. Unsupported Shopping content treats services as "labour, time, effort, expertise or actions which don't result in ownership of a tangible product," including services bundled with goods. That is the eligibility bar for Shopping ads and free listings, not a ranking rule.

Service is not in the search gallery. It can wait until the Search types above are in place.

Organization example (site-wide)

Place this on the home page or a single About page, not on every URL. Use the most specific Organization subtype that matches the business (OnlineStore for ecommerce). Keep values identical to what the page displays.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Example Corporation",
  "url": "https://www.example.com",
  "logo": "https://www.example.com/images/logo.png",
  "sameAs": [
    "https://example.net/profile/example1234",
    "https://example.org/example1234"
  ],
  "email": "contact@example.com",
  "telephone": "+44-20-0000-0000",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "1 Example Street",
    "addressLocality": "London",
    "postalCode": "EC1A 1AA",
    "addressCountry": "GB"
  }
}
</script>

What not to spend a sprint on

Do not implement FAQPage or HowTo for Google Search features. Google added a deprecation notice on 8 May 2026. The FAQ rich result was no longer shown from 7 May 2026. That notice said Google would drop the FAQ search-appearance filter, the FAQ rich result report, and Rich Results Test support in June 2026, and Search Console API support in August 2026. Google removed the FAQ rich result documentation on 15 June 2026. HowTo rich results were already removed, with documentation taken down on 14 September 2023. Neither type is a current Search appearance to ticket.

Leaving old FAQPage or HowTo markup on a page is not the same as building it now. Do not recommend either as a current Search feature, and do not treat leftover FAQ markup as an AI-visibility tactic (see Structured data and AI features).

Skip the rest of the gallery unless that feature is the product: Job posting, Recipe, Math solver, Event, Course list, Vacation rental, and similar types. They are real Search features for the sites they describe. They are not a default schema backlog for a retailer, publisher, marketplace, or SaaS company.

Kitchen-sink schema.org types that never appear in the gallery (WebPage plus every possible property, and similar) are optional graph work. CollectionPage on a category template is that kind of hygiene, not a Search exception (Category pages, collections, and pagination).

Connecting entities with @id fragments

A page can describe more than one thing. Google Search understands multiple items whether you nest them under one main type or list them as separate objects. The quality rule is unchanged: include the main type that reflects the main focus of the page. A video on a recipe page does not make the page eligible as a recipe rich result unless Recipe is there too.

When those objects need to refer to the same entity without repeating it, give the entity an @id and point at that identifier. For in-page nodes, Google's Search Central examples use a URL fragment (they write #main-author). That fragment names a node on this page. It is not a new crawlable URL. Google Search generally does not support HTML fragment URLs as distinct pages; @id fragments are RDF identifiers in the graph, not a way to get /page#foo indexed.

The short form (#person) and the expanded form (https://www.example.com/authors/marlo-smith#person) are the same kind of identifier. Use the expanded form when the node must be reused from another URL. Google's January 2024 hashtag change is the short form, shown after this example.

mainEntity is how a page-typed node names that focus. schema.org defines it as the primary entity described by the page. Google requires it on Profile page markup, and uses a fragment @id so other objects can point at the person without duplicating the node:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "ProfilePage",
  "@id": "https://www.example.com/authors/marlo-smith#page",
  "url": "https://www.example.com/authors/marlo-smith",
  "mainEntity": {
    "@id": "https://www.example.com/authors/marlo-smith#person",
    "@type": "Person",
    "name": "Marlo Smith",
    "url": "https://www.example.com/authors/marlo-smith"
  },
  "hasPart": [{
    "@type": "Article",
    "@id": "https://www.example.com/articles/things-to-see-in-new-jersey#article",
    "headline": "Things to see in New Jersey",
    "url": "https://www.example.com/articles/things-to-see-in-new-jersey",
    "datePublished": "2014-02-23T18:34:00Z",
    "author": { "@id": "https://www.example.com/authors/marlo-smith#person" }
  }]
}
</script>

That pattern is for profile pages (a creator page whose primary focus is one person or organisation). Do not add ProfilePage to a product or article URL to "force" mainEntity. On those templates, the main type is the focus (Product, Article). Nest related nodes, or connect them with @id fragments when the same entity is referenced more than once (a brand on the product and on the seller, an author on several pieces). Wrapping every URL in WebPage plus mainEntity is schema.org graph hygiene, not a Search ticket.

The January 2024 documentation change is the short in-page form of that same graph. Google switched in-page @id examples to hashtags so a bare token became a fragment. Same nodes as above; only the @id values change. Existing identifiers without # still work; you do not need to rewrite them.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "ProfilePage",
  "@id": "#page",
  "url": "https://www.example.com/authors/marlo-smith",
  "mainEntity": {
    "@id": "#person",
    "@type": "Person",
    "name": "Marlo Smith",
    "url": "https://www.example.com/authors/marlo-smith"
  },
  "hasPart": [{
    "@type": "Article",
    "@id": "#article",
    "headline": "Things to see in New Jersey",
    "url": "https://www.example.com/articles/things-to-see-in-new-jersey",
    "datePublished": "2014-02-23T18:34:00Z",
    "author": { "@id": "#person" }
  }]
}
</script>

Category pages, collections, and pagination

Pagination for Google Search is not a structured-data problem. Google's current ecommerce pagination guidance is HTML: sequential <a href> links to the next page, a unique URL for each page (for example ?page=2), a self-referencing canonical on every page in the series, and no fragment identifiers for page numbers. Google ignores the text after # when deciding whether two URLs are the same.

Linking later pages back to the first page of the collection is a hint that page 1 may be the better landing page. Google stopped using rel="prev" and rel="next" as indexing signals in 2019. Canonicals, crawlable next links, and what not to canonicalise to page 1 are covered in Canonical tags and Duplicate content; filter-plus-pagination is in Faceted navigation.

CollectionPage is a schema.org WebPage subtype for a page that is a collection: a category, a listing, a paginated series. It is not in the search gallery. It does not create a rich result, and it does not tell Googlebot which URL to crawl next. If you already emit JSON-LD on category templates, typing the page as CollectionPage and pointing mainEntity at an ItemList of the items visible on this page is coherent graph markup. Do this once the Search types are in place. It is not a substitute for next links or self-canonicals.

ItemList is a Search feature when it is combined with Recipe, Movie, Course, or Restaurant on a summary page (a host carousel). That is not a generic ecommerce or publishing category. Do not wrap a 200-SKU product listing in ItemList and expect a carousel.

List only items the user can see on that URL. Page 2 of running shoes is its own CollectionPage at /categories/running-shoes?page=2, not a fragment of page 1, and its ItemList is the products on page 2.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "CollectionPage",
  "@id": "https://www.example.com/categories/running-shoes#page",
  "url": "https://www.example.com/categories/running-shoes",
  "name": "Running shoes",
  "mainEntity": {
    "@id": "https://www.example.com/categories/running-shoes#list",
    "@type": "ItemList",
    "itemListElement": [
      {
        "@type": "ListItem",
        "position": 1,
        "url": "https://www.example.com/products/trail-runner"
      },
      {
        "@type": "ListItem",
        "position": 2,
        "url": "https://www.example.com/products/road-racer"
      }
    ]
  }
}
</script>

Quality rules that fail otherwise-valid markup

The Rich Results Test catches missing required properties and broken syntax. It does not catch most quality failures. Those still make the page ineligible, and they are the usual reason "valid" markup never appears.

Markup must match content that is visible to readers of the page. If JSON-LD describes a performer, price, rating, or policy, the HTML body must describe the same thing. Hidden, outdated, or embellished properties are a quality violation, not a clever optimisation.

From the general structured data guidelines:

  • Relevance: the markup must be a true representation of the page. Do not label instructions as recipes, or a broadcast as a local event, to chase a feature.
  • Completeness: missing required properties means the item is not eligible. Prefer fewer complete, accurate recommended properties over a full set of thin or invented ones.
  • Location: put the structured data on the page it describes, unless that feature's documentation says otherwise. If you have duplicate URLs for the same content, put the same structured data on the duplicates, not only on the canonical.
  • Images: image URLs in markup must be crawlable and indexable, and the image must be relevant to the page.
  • Access: do not block the page from Googlebot with robots.txt, noindex, or login if you want the rich result.
  • Reviews: do not mark up fake reviews, undisclosed incentivised reviews, or ratings aggregated from other websites. For local businesses and organisations, ratings must be sourced directly from users; you cannot review yourself and keep the star feature.

A page can carry more than one item (a product plus breadcrumbs, an article plus a video) when those items are visible on the page. Include the main type that reflects the main focus of the page. When those items need to refer to the same entity, connect them with @id fragments rather than duplicating the node (Connecting entities with @id fragments).

Keep JSON-LD tied to what the page renders

Consistent JSON-LD is a data problem, not a copywriting task. The script has to be generated from the same fields that already render in the HTML, for a known template, in a known order. If someone pastes a JSON-LD block into a CMS field and later changes the visible price, the Rich Results Test can still report valid while the page already fails the quality rule that markup must match what readers see (Quality rules that fail otherwise-valid markup).

Most inconsistencies are drift, not a missing @type. They appear when nobody has catalogued, per template:

  • which page elements need markup
  • which Google Search type those elements map to (and only that type)
  • which properties are static (brand name, organisation @id) and which are dynamic (price, availability, rating, headline, image)
  • where those dynamic values come from (PIM, product feed, CMS) so a template change cannot drop them silently

Build that inventory before the first JSON-LD ticket, then generate the script from those fields. Hand-edited blocks and Tag Manager tags that are not bound to visible page content are how drift starts (Can engineering inject JSON-LD with JavaScript or Tag Manager?). A new product template that drops offers is the same failure showing up in Search Console (How to test and monitor).

Where the markup lives

JSON-LD can sit in head or body. Google can process JSON-LD injected by JavaScript once it is in the rendered DOM. That support is real; it is not the default you should choose.

For Product markup, Google's October 2024 documentation update recommends putting Product structured data in the initial HTML for best results. If you generate Product markup with JavaScript, Google also says to make sure the server can handle the extra traffic.

The JavaScript SEO article still prefers server-rendering structured data for the same reason it prefers server-rendering other critical content: there is a delay between crawl and render, and rendering timeouts or errors can drop injected JSON-LD. Present both facts to the team:

  • Google supports JavaScript-injected JSON-LD.
  • Server-rendered JSON-LD in the initial HTML is the safer default, especially for Product.

Do not block structured-data pages from Googlebot. Do not create empty pages whose only job is to hold markup. Organization markup belongs on the home page or one About page, not in the footer of every URL (Organization example (site-wide)).

How to test and monitor

During development, use the Rich Results Test. It validates supported types and, for some features, previews the appearance. It will not show types Google does not use for rich results; for those, use the Schema Markup Validator (Google's documentation versus schema.org). If you are testing a type neither tool is meant to preview, inspect the rendered HTML and confirm the JSON-LD is present after JavaScript runs.

After launch, use Search Console's rich result status reports and the URL Inspection tool. Watch for:

  • Invalid items after a template change (a new product template that drops offers or aggregateRating).
  • Valid item counts falling without a matching rise in errors (markup removed, or no longer served on the canonical HTML).
  • Manual actions for structured data, which remove rich-result eligibility until you fix the issue.

Google's introduction page describes a before-and-after test on stable URLs as the honest way to measure effect: add valid markup, confirm Google has found it, then compare Search Console performance for those URLs over several months. Do not use a seasonal product URL as the test set.

Structured data and AI features

AI Overviews and AI Mode have no additional technical requirements beyond the page being indexed and eligible to be shown in Google Search with a snippet. Matching structured data to the visible text on the page is listed there as ordinary SEO hygiene, alongside crawlability, internal links, and text that is actually in the HTML. It is not a special AEO (answer-engine optimisation) requirement.

That matches the conservative position in How LLMs and RAG systems retrieve, rank, and cite content: implement structured data for its proven benefits in traditional search. Do not treat schema as an AI-visibility lever in the way it functions for rich results. Entity clarity and content quality remain the more reliable signals.

FAQs

Should we still add FAQPage or HowTo?

Not as a Google Search feature. The FAQ rich result stopped showing on 7 May 2026. Google's notice said the FAQ search-appearance filter, the rich result report, and Rich Results Test support would go in June 2026, with Search Console API support in August 2026. The documentation was removed on 15 June 2026. HowTo rich results were removed in 2023. Visible FAQs on a page remain useful for users; they do not need FAQPage markup to do that job, and HowTo markup will not restore a retired appearance.

Can engineering inject JSON-LD with JavaScript or Tag Manager?

Yes. Google can read JSON-LD in the rendered DOM. For Product, put the markup in the initial HTML unless you have a documented reason not to. For every other type, server-render it if you can. If you use Tag Manager, bind variables to visible page content so the tag cannot invent a price, rating, or name that the HTML does not show.

Can we use Product markup for services?

No. Product snippets and merchant listings are for a specific product. A service page is not that page. schema.org Product includes services; Google Search Product features do not. schema.org Service is not a Google Search feature (Product is for a product, not a service).

Which types should we ticket first?

Ecommerce and marketplace: Product (initial HTML) on product pages, Organization on home or About, Breadcrumb on category and product templates, Review snippet only where reviews are genuine and visible. Publishing: Article plus Organization, and Video only on dedicated watch pages (Video SEO). SaaS: Organization plus Article for the editorial site. Do not mark a consulting engagement or a monthly SaaS plan as Product; that is a service. Add Product only if you sell a specific product that matches the Product feature, and add gallery types such as Software app only if that is the product.

Key takeaways

  1. Markup, eligibility, and appearance are three layers: valid JSON-LD is an input, not a ranking change, and Google may withhold a rich result even when the page is eligible.
  2. Google Search Central is the Search spec; schema.org is the vocabulary: types missing from the search gallery can wait until nothing more impactful is left.
  3. Ticket documented Search types on matching pages: Product on product pages, not services. Do not ticket FAQPage or HowTo, and skip other gallery types unless that feature is the product.
  4. Generate JSON-LD from the same fields the page renders, and server-render it: Product markup belongs in the initial HTML. Hand-edited blocks drift.
  5. AI Overviews add no extra schema requirement: implement structured data for traditional Search features, not as an AI-visibility shortcut.

Further reading

Original content researched and drafted by the author. AI tools may have been used to assist with editing and refinement.

Share this article

Your Brand, VISIVELY!