Schema Markup for Product Category Pages

When optimizing an eCommerce site, most people focus on adding structured data to individual product pages. But your product category pages are just as important. These pages help users browse through multiple items and guide them toward conversions, so search engines should understand their structure, too.

Adding the right schema markup for product category pages clarifies what your page contains and how each product relates to the whole collection. 

This improves how search engines interpret your site and may even help your listings qualify for new features like carousel rich results (beta).

What is the purpose of schema on product category pages?

Structured data, or schema markup, gives search engines a detailed understanding of your page’s purpose and contents.

For product listing pages, schema helps Googlebot and other crawlers understand:

  • That the page contains a list of products, not a single product
  • The relationship between the category page and its product detail pages
  • The context for rich results and future search features (e.g., product carousels)

When you correctly implement schema for product category pages, it doesn’t directly increase rankings, but it improves how search engines interpret and display your content. In other words, it strengthens your eligibility for enhanced search experiences.

Product category page schema markup visualization
A visualization of schema markup on a product category page

Which schema should you use for a product category page?

For an eCommerce website, you can use a combination of CollectionPage, ItemList, and Product schema types on the product category page. This layered approach tells Google that your page is a collection of products, not a single product page.

You can connect these layers using the mainEntity property. This tells search engines that the ItemList (i.e. the list of products) is the primary content of the page.

Here’s what the hierarchy looks like for product schema markup for category pages:

Each layer builds on the previous one:

  • CollectionPage identifies the page as a product category or collection page.
  • ItemList defines that the main content is a list of products.
  • Product provides structured information for each item on that list (name, image, price, etc.).

This three-tiered structure provides complete semantic clarity and helps search engines accurately interpret your content hierarchy.

How to implement schema markup on product category pages

Below is a step by step guide on the ideal implementation using the CollectionPage → mainEntity → ItemList → Product structure.

Step 1: Define the CollectionPage

Every category page is a type of webpage that collects similar items and this is best represented by CollectionPage.

    {
      "@type": "CollectionPage",
      "@id": "https://www.example.com/categories/outerwear#collectionpage",
      "name": "Outerwear",
      "url": "https://www.example.com/categories/outerwear",
      "description": "Browse our selection of outerwear including waterproof coats, wool overcoats, and insulated parkas.",
      "mainEntity": { "@id": "https://www.example.com/categories/outerwear#itemlist" }
    },

This tells search engines that the page itself is a collection page designed to showcase multiple related products.

Also, use the mainEntity property to connect your CollectionPage to an ItemList with the specific @id. This linkage clarifies that the main content of the page is a list of products.

You can also enrich your CollectionPage with additional context, such as information about your website, publisher, or organization, to help search engines understand the page’s ownership and structure.

Step 2: Add the ItemList and Product Details

Next, define the ItemList that represents the main content of your page. The ItemList tells search engines that this section is a list of items. In this case, products displayed on your category page.

Each item within the list should be marked up as a ListItem with a numerical position and a nested Product object containing its key details.

The Product schema provides search engines with structured information about each individual item, including its name, image, url, offers, and (if available) aggregateRating.

This helps Google understand that these items are distinct entities within the same category and may also improve how they appear in Search results, especially for queries with commercial intent.

    {
      "@type": "ItemList",
      "@id": "https://www.example.com/categories/outerwear#itemlist",
      "name": "Outerwear product list",
      "itemListOrder": "https://schema.org/ItemListUnordered",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "item": {
            "@type": "Product",
            "name": "Waterproof Winter Coat",
            "image": [
              "https://www.example.com/images/waterproof-winter-coat-1x1.jpg",
              "https://www.example.com/images/waterproof-winter-coat-4x3.jpg",
              "https://www.example.com/images/waterproof-winter-coat-16x9.jpg"
            ],
            "url": "https://www.example.com/products/waterproof-winter-coat",
            "offers": {
              "@type": "Offer",
              "price": "120.00",
              "priceCurrency": "EUR",
              "availability": "https://schema.org/InStock"
            },
            "aggregateRating": {
              "@type": "AggregateRating",
              "ratingValue": "4.8",
              "reviewCount": "214"
            }
          }
        },
        {
          "@type": "ListItem",
          "position": 2,
          "item": {
            "@type": "Product",
            "name": "Wool Blend Overcoat",
            "image": [
              "https://www.example.com/images/wool-blend-overcoat-1x1.jpg",
              "https://www.example.com/images/wool-blend-overcoat-4x3.jpg",
              "https://www.example.com/images/wool-blend-overcoat-16x9.jpg"
            ],
            "url": "https://www.example.com/products/wool-blend-overcoat",
            "offers": {
              "@type": "Offer",
              "price": "189.00",
              "priceCurrency": "EUR",
              "availability": "https://schema.org/InStock"
            },
            "aggregateRating": {
              "@type": "AggregateRating",
              "ratingValue": "4.6",
              "reviewCount": "89"
            }
          }
        },
        {
          "@type": "ListItem",
          "position": 3,
          "item": {
            "@type": "Product",
            "name": "Insulated Parka",
            "image": [
              "https://www.example.com/images/insulated-parka-1x1.jpg",
              "https://www.example.com/images/insulated-parka-4x3.jpg",
              "https://www.example.com/images/insulated-parka-16x9.jpg"
            ],
            "url": "https://www.example.com/products/insulated-parka",
            "offers": {
              "@type": "Offer",
              "price": "149.00",
              "priceCurrency": "EUR",
              "availability": "https://schema.org/OutOfStock"
            },
            "aggregateRating": {
              "@type": "AggregateRating",
              "ratingValue": "4.9",
              "reviewCount": "342"
            }
          }
        }
      ]
    }

This block captures all visible products on the category page.

You can also use the itemListOrder property to indicate whether the products are sorted in ascending, descending, or unordered order.

While this field doesn’t affect rankings or eligibility for rich results, it improves semantic clarity, especially if your category page allows sorting by price, rating, or date.

💡 Pro Tip:
If your site uses pagination, only include the products that are actually visible to users on the current page.

Step 3: Combine Using @graph

Finally, combine your CollectionPage and ItemList nodes into a single JSON-LD block using @graph.

This approach keeps your schema well-organized and ensures all entities are linked together in a single, crawlable data structure.

The @graph container allows you to declare multiple entities (like WebSite, CollectionPage, and ItemList) within one script tag while maintaining clear relationships between them through @id references.

It’s especially helpful for large eCommerce sites where each page can contain multiple schema types that need to coexist cleanly.

<script type="application/ld+json">

{

  "@context": "https://schema.org",

  "@graph": [

    { ...CollectionPage... },

    { ...ItemList... }

  ]

}

</script>

⚠️ Important Note:

Adding an @id makes your structured data more precise and helps connect entities within the graph.

However, Google’s Rich Results Test may not detect the Carousel when the top-level ItemList includes an @id.

If your primary focus is appearing in rich results only, you can simply use the ItemList block without @id and CollectionPage.

Product category page schema markup example

Below is an JSON-LD example for product category pages:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "CollectionPage",
      "@id": "https://www.example.com/categories/outerwear#collectionpage",
      "name": "Outerwear",
      "url": "https://www.example.com/categories/outerwear",
      "description": "Browse our selection of outerwear including waterproof coats, wool overcoats, and insulated parkas.",
      "publisher": { "@id": "https://www.example.com/#publisher" },
      "mainEntity": { "@id": "https://www.example.com/categories/outerwear#itemlist" }
    },
    {
      "@type": "Person",
      "@id": "https://www.example.com/#publisher",
      "name": "Aubrey Yung",
      "url": "https://www.aubreyyung.com/about/"
    },
    {
      "@type": "ItemList",
      "@id": "https://www.example.com/categories/outerwear#itemlist",
      "name": "Outerwear product list",
      "itemListOrder": "https://schema.org/ItemListUnordered",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "item": {
            "@type": "Product",
            "name": "Waterproof Winter Coat",
            "image": [
              "https://www.example.com/images/waterproof-winter-coat-1x1.jpg",
              "https://www.example.com/images/waterproof-winter-coat-4x3.jpg",
              "https://www.example.com/images/waterproof-winter-coat-16x9.jpg"
            ],
            "url": "https://www.example.com/products/waterproof-winter-coat",
            "offers": {
              "@type": "Offer",
              "price": "120.00",
              "priceCurrency": "EUR",
              "availability": "https://schema.org/InStock"
            },
            "aggregateRating": {
              "@type": "AggregateRating",
              "ratingValue": "4.8",
              "reviewCount": "214"
            }
          }
        },
        {
          "@type": "ListItem",
          "position": 2,
          "item": {
            "@type": "Product",
            "name": "Wool Blend Overcoat",
            "image": [
              "https://www.example.com/images/wool-blend-overcoat-1x1.jpg",
              "https://www.example.com/images/wool-blend-overcoat-4x3.jpg",
              "https://www.example.com/images/wool-blend-overcoat-16x9.jpg"
            ],
            "url": "https://www.example.com/products/wool-blend-overcoat",
            "offers": {
              "@type": "Offer",
              "price": "189.00",
              "priceCurrency": "EUR",
              "availability": "https://schema.org/InStock"
            },
            "aggregateRating": {
              "@type": "AggregateRating",
              "ratingValue": "4.6",
              "reviewCount": "89"
            }
          }
        },
        {
          "@type": "ListItem",
          "position": 3,
          "item": {
            "@type": "Product",
            "name": "Insulated Parka",
            "image": [
              "https://www.example.com/images/insulated-parka-1x1.jpg",
              "https://www.example.com/images/insulated-parka-4x3.jpg",
              "https://www.example.com/images/insulated-parka-16x9.jpg"
            ],
            "url": "https://www.example.com/products/insulated-parka",
            "offers": {
              "@type": "Offer",
              "price": "149.00",
              "priceCurrency": "EUR",
              "availability": "https://schema.org/OutOfStock"
            },
            "aggregateRating": {
              "@type": "AggregateRating",
              "ratingValue": "4.9",
              "reviewCount": "342"
            }
          }
        }
      ]
    }
  ]
}
</script>

Best Practices for Product Category Schema Markup

1. Use CollectionPage as the parent schema

Every product category or listing page should begin with a CollectionPage schema type.

This signals to Google that the page’s purpose is to showcase a group of related products, not one specific product.

It defines the context for all the structured data that follows, including the product list itself.

Without CollectionPage, search engines may not correctly interpret your category pages, potentially treating them as standard web pages or single product entries.

By explicitly using it, you establish a clear distinction between product detail pages and category pages, which is critical for accurate indexing and structured understanding.

After defining your category page as a CollectionPage, connect it to an ItemList using the mainEntity property.

This communicates that the ItemList — the list of products — is the primary content of the page.

Using mainEntity makes your schema both standards-compliant and semantically accurate.

It ensures Google understands that your category page’s main purpose is to display a list of items, not blog content, banners, or filters.

This explicit relationship between CollectionPage and ItemList also improves data organization for potential features like the carousel rich results (beta).

3. Include complete product details

Each product within your ItemList should be represented by a complete Product object.

At minimum, include name, image, url, brand, and offers — with the offer specifying price, priceCurrency, and availability.

Comprehensive product data ensures your schema is valid, complete, and eligible for product-related enhancements.

When properties are missing or inconsistent, Google may ignore your markup or issue warnings in Search Console.

Accurate data also makes it easier to maintain consistency between your schema, product feeds, and user-visible content.

4. Use the correct itemListOrder

The itemListOrder property defines whether the items in your list are sorted, ranked, or unranked.

It helps search engines interpret how your items are presented on the page.

Choose the value that accurately reflects the order displayed on your page:

  • Use ItemListOrderAscending for lists sorted low to high (e.g., “Price: Low to High”).
  • Use ItemListOrderDescending for lists sorted high to low (e.g., “Newest First” or “Top Rated”).
  • Use ItemListUnordered when there’s no fixed order — the most common case for category pages.

This small detail gives search engines more context about how your products are presented.

If no order is implied, ItemListUnordered keeps your markup accurate and avoids misleading signals about ranking.

5. Only include visible products

Your schema should reflect exactly what users see on the page.

If your category uses pagination, filters, or infinite scroll, only include the products that are currently visible.

Adding hidden or next-page products to your markup can create discrepancies between your structured data and HTML content.

For paginated lists, include a separate schema for each page, describing only that page’s products.

Consistency between visible content and structured data maintains Google’s trust and ensures eligibility for rich results.

6. Keep URLs canonical

Each Product’s url property must match the canonical URL of that product’s detail page.

Avoid including tracking parameters, filters, or temporary session IDs in your structured data.

Google uses URLs to connect product listings with their detail pages — inconsistencies can break that connection.

By maintaining canonical consistency, you ensure that your category schema reinforces the same URL relationships that your site architecture defines.

This helps with de-duplication, strengthens internal linking signals, and supports clearer data connections across your product ecosystem.

Common mistakes in category page schema

1. Marking the category page as a Product

A common and critical mistake is labeling a product category page as a single Product.

This completely misrepresents the page’s purpose because a category page displays multiple products, not one item.

Marking your page as CollectionPage clearly communicates that the page is a collection of individual products, each described in its own schema object.

It’s the single most important step to ensure proper interpretation by search engines.

2. Add reviews or ratings to the entire Page

Some sites mistakenly add Review or AggregateRating properties to the CollectionPage or ItemList.

This is incorrect because reviews and ratings are meant to describe individual products, not entire collections.

If you display product ratings in your category, nest the rating within each Product object:

"aggregateRating": {

  "@type": "AggregateRating",

  "ratingValue": "4.7",

  "reviewCount": "235"

}

By keeping ratings tied to specific products, you provide clear, item-level context that Google can use in structured snippets.

3. Not Linking to the Product Detail Page

One of the most frequent issues with product category schema is failing to link each Product to its dedicated product detail page using the url property.

Every product listed within your ItemList should include a canonical, crawlable URL that points directly to the product’s individual page — not to the image, a filtered parameter, or the category itself.

This link allows Google to understand that each product in your category page is a separate entity with more detailed information available elsewhere on your site.

When the url is missing or incorrect, search engines may:

  • Treat the products as incomplete entities,
  • Fail to connect them to their corresponding detail pages, or
  • Omit them entirely from rich result eligibility.

4. Mismatched information between category and product detail pages

A common oversight in structured data implementation is having inconsistent information between the product data shown on a category page and the details on the product’s individual page.

For example, your category schema might list a product with a price of €120 and a “4.8” rating, while the actual product page shows a different price or updated rating.

When a product’s name, price, availability, or aggregateRating differ between your category schema and product schema, it can appear as though your data is out of sync or unreliable.

So, make sure that category pages pull live product data from the same source as your product detail pages.

If your site uses dynamic updates (e.g., for stock or pricing), make sure both pages update simultaneously so that your schema markup remains consistent across your site.

5. Mixing Different Content Types in the ItemList

Another frequent mistake in eCommerce schema markup is including different types of entities within the same ItemList.

For example, some category pages mix Product, Article, or Service items under one ItemList.

While this may pass a basic validation check, it violates Google’s structured data guidelines — which state that all ListItem elements in an ItemList must represent the same type of content.

In practical terms, if your category page is about products, every itemListElement should point to a Product object — not a blog post, video, or service listing.

Mixing content types in your eCommerce schema markup can confuse Google about the primary purpose of the page and prevent your structured data from being eligible for product-related rich results or carousels.

Keeping your list type-consistent ensures your eCommerce schema markup clearly signals to Google that your category page focuses on products, not mixed content. This consistency improves eligibility for carousel and product-rich results.

Google’s Carousel structured data is an experimental feature that allows eligible pages to display multiple products directly in a horizontally scrollable carousel in search results. This format uses ItemList combined with a supported type such as Product—making your product schema markup for category pages perfectly suited for it.

However, this feature is still in beta and not yet widely available. It’s currently limited to specific regions (EEA countries, Turkey, and South Africa) and certain query types. Even with valid markup, Google doesn’t guarantee that your carousel will appear.

Still, implementing the CollectionPage + ItemList + Product structure ensures your schema is fully compatible with this emerging feature — and ready for it when it becomes widely supported.

Your goal is to implement the correct structured data now so your pages are ready when it expands globally.

💡 Even with valid markup, Carousel appearance isn’t guaranteed.

Final Thoughts

By using CollectionPage, ItemList, and Product schema together, you establish a logical hierarchy that mirrors how shoppers actually browse your catalog.

Search engines gain a clearer understanding of your content, while customers benefit from richer, more informative search results that help them make decisions before even clicking through.

Even if Google’s Carousel feature isn’t available in your region yet, implementing valid, layered structured data prepares your site for future search enhancements.

Frequently Asked Questions

How does Googlebot use structured data on category pages?

Googlebot uses schema markup to identify entities (like products) and relationships (like lists or pages).
For category pages, it helps map product collections and understand that these items belong together under a specific theme.

Does schema on category pages improve rankings?

Not directly. Schema markup doesn’t boost rankings by itself, but it helps Google interpret your content more accurately.
This can indirectly improve click-through rates and visibility in rich search features.

What is the impact of category page schema on Google rich snippets?

When implemented correctly, it can make your product listings eligible for richer snippets or carousel-based displays.
Even if these aren’t shown yet, proper schema increases the likelihood of future feature eligibility.

Can you use ProductGroup on a category page?

No, ProductGroup is not meant for product category pages. ProductGroup is used to represent a group of products that share the same model but vary by specific attributes, such as size, color, or material.
Category pages should use CollectionPage with an ItemList of Product items, since each listing represents a distinct product rather than variants of the same model.

What tools can you use to test product category schema markup?

You can use Rich Results Test to check eligibility for Google Search features or Schema Markup Validator to verify schema markup correctness and relationships.

What’s the difference between ItemList and CollectionPage schema?

While ItemList describes the data — the list of items on your page, such as products or articles — CollectionPage represents the container, meaning the entire page that displays that list.
ItemList helps Google understand the structure and content of your product listings, and CollectionPage provides context about the page itself, including its name, URL, and purpose.
In short, while ItemList defines what’s inside, CollectionPage defineswhere it lives — and you need both for a complete, well-structured product category page.

Aubrey Yung

Aubrey Yung

Aubrey is an SEO Manager with 6+ years of B2B and B2C marketing experience. Outside of work, she loves traveling and learning languages.