Structured data for product category pages: ItemList, Product, and what not to mark up
A product category page and an individual product page answer different questions, and Google's structured data vocabulary treats them differently. Marking up a category page as if it were one giant product page is the single most common mistake on generated e-commerce sites.
A category page and a product page are different entities
A product page describes one thing: a specific item with a price, an availability status, and (where genuinely collected) reviews. A category page describes a collection: a filtered or browsed list of many things. Schema.org gives each its own type for a reason — Product for the single entity, ItemList for the collection.
The test that resolves most confusion: does this page have exactly one price? If yes, it's a product page and gets full Product markup. If it lists many prices, it's a listing and gets ItemList.
ItemList: what it tells Google about a listing
When a page lists several distinct products, Google's own guidance for product structured data covers this case directly: mark up the page with ItemList, where each itemListElement is a ListItem pointing to a lightweight Product reference — typically name, url and image. This tells Google what the page is a list of.
What it does not do is substitute for the merchant listing rich results — the snippets showing price, availability and star ratings next to a product in search. Those are tied to the individual product page's full Product markup and, in most cases, to a Google Merchant Center feed kept in sync with it.
Breadcrumbs on a deep category hierarchy
Category trees are usually where breadcrumb markup earns its keep. A BreadcrumbList that mirrors the visible trail — department, category, subcategory — gives Google an explicit hierarchy independent of URL structure, which matters more as depth increases and as facets multiply URL variants of the same node.
Each ListItem needs a position, a name, and an item URL that resolves to a real, canonical page. A breadcrumb pointing to a filtered or paginated variant instead of the canonical category page is a common source of mismatch between the visible trail and the markup.
A working JSON-LD example
{
"@context": "https://schema.org",
"@type": "ItemList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"item": {
"@type": "Product",
"name": "Trail running shoe — model A",
"url": "https://example.com/shoes/trail-running/model-a",
"image": "https://example.com/images/model-a.jpg"
}
},
{
"@type": "ListItem",
"position": 2,
"item": {
"@type": "Product",
"name": "Trail running shoe — model B",
"url": "https://example.com/shoes/trail-running/model-b",
"image": "https://example.com/images/model-b.jpg"
}
}
]
}
Note what is absent: no offers, no aggregateRating, no review on the category page's entries. Those fields belong on the destination product page, where the claim they make (this exact price, this exact rating) is verifiable in context.
Five mistakes that invalidate a batch
- Marking up every facet combination as a distinct ItemList. Filtered and sorted URLs of the same category produce near-duplicate structured data at scale, which is the templated-page equivalent of thin content.
- Copying full Product offers onto the category page. A price shown on a listing page is a snapshot; the source of truth is the product page. Duplicating
offersdata in two places invites drift and inconsistency Google can detect. - Skipping BreadcrumbList on deep hierarchies. The deeper the category tree, the more the markup earns its cost — and the more expensive it is to omit.
- Item count mismatch. An
ItemListclaiming 40 products when the visible page shows 12 (because of pagination or lazy loading) is inconsistent with what a user actually sees, which is exactly the kind of markup-versus-content mismatch Google's structured data guidelines flag. - Invalid JSON syntax at scale. A single trailing comma in a shared template can invalidate structured data across an entire category tree at once. This is the same failure mode covered in structured data on generated pages, and it is worth the same automated check there.
Validating before publish
- Rich Results Test — confirms which enhancements Google's parser recognises for the URL as submitted.
- Schema Markup Validator — checks conformance to the schema.org vocabulary independent of Google-specific eligibility.
- Search Console's Enhancement reports — the only view that reflects what is actually indexed and parsed at scale, after the fact rather than before.
On a templated category tree, validate one representative URL per template variant before a batch goes live, then spot-check the Enhancement reports weekly for the first month — the same publish-then-verify discipline used for canonical tags on templated pages.
What structured data does not do
Valid, well-scoped structured data never guarantees a ranking improvement or a rich result. Google treats markup as a hint about what a page contains, not an instruction about how to display it — eligibility for any enhancement still depends on Google's own policies and, for many product features, on signals outside the JSON-LD itself. Treat every claim in this article as what it is: a description of what is technically supported, not a promise of visibility.
Frequently asked questions
Does adding Product markup to a category page create a rich result for every product?
Not directly. The merchant listing rich results that show price, availability and ratings are tied to the individual product page's Product markup, and often to a linked Google Merchant Center feed. An ItemList on a category page helps Google understand what the page lists, but it is not a shortcut to per-product rich results.
Do I still need Google Merchant Center if I mark up products with JSON-LD?
For price and availability to appear in Shopping surfaces and certain rich results, yes in most cases. JSON-LD structured data and Merchant Center feeds serve overlapping but separate purposes, and product rich results increasingly rely on the feed being present and consistent with the page.
What's the practical difference between category page and product page markup?
A category page marks up a list: an ItemList whose entries reference each Product lightly, typically name, url and image. A product page marks up one entity fully: Product with offers, price, availability and, where genuinely present, aggregateRating and review.
Sources
SEOFactory
Want to apply this to your own site?
SEOFactory designs the SEO architecture, produces structured content and strengthens internal linking to grow organic visibility over time.
Get in touch