Most Shopify themes include basic structured data — a minimal Product schema and perhaps a BreadcrumbList. This baseline gets your products indexed with price information, but it leaves significant rich result opportunities untapped. Star ratings, FAQ dropdowns, availability badges, and review counts in search results all require specific schema properties that basic implementations miss.

This guide covers the structured data implementation that separates stores ranking with rich results from those showing plain blue links. We implement this as part of our SEO and Shopify development services, building on the foundations covered in our basic schema markup guide.

Why structured data matters for ecommerce

Structured data tells search engines exactly what your content means, not just what it says. For ecommerce, this translates directly into richer search listings that attract more clicks. Product rich results with star ratings consistently achieve 20–35% higher click-through rates than plain results — and for competitive keywords, that CTR advantage can mean thousands of additional visits per month.

Google supports rich results for several schema types relevant to Shopify stores:

  • Product — price, availability, review ratings in search results.
  • AggregateRating — star ratings displayed directly in search.
  • FAQPage — expandable FAQ sections in search results.
  • BreadcrumbList — breadcrumb navigation in search results instead of URL.
  • HowTo — step-by-step instructions (useful for product guides).
  • Organisation — knowledge panel eligibility for branded searches.

Rich results are not guaranteed — Google decides whether to display them. But valid, comprehensive structured data is a prerequisite. You cannot earn rich results without it.

Rich results examples for Shopify product pages in Google Search
Rich results significantly increase the visual prominence and click-through rate of your search listings. Star ratings and price information are the most impactful for ecommerce.

Comprehensive Product schema

A complete Product schema includes far more than the name, price, and image that basic implementations provide. Here is the full implementation pattern for Shopify product pages:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": {{ product.title | json }},
  "description": {{ product.description | strip_html | truncate: 5000 | json }},
  "image": [
    {%- for image in product.images limit: 5 -%}
      "{{ image | image_url: width: 1200 }}"{% unless forloop.last %},{% endunless %}
    {%- endfor -%}
  ],
  "sku": {{ product.selected_or_first_available_variant.sku | json }},
  "mpn": {{ product.selected_or_first_available_variant.barcode | json }},
  "brand": {
    "@type": "Brand",
    "name": {{ product.vendor | json }}
  },
  "url": "{{ shop.url }}{{ product.url }}",
  {%- if product.metafields.reviews.rating.value -%}
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": {{ product.metafields.reviews.rating.value.rating | json }},
    "reviewCount": {{ product.metafields.reviews.rating_count | json }},
    "bestRating": "5",
    "worstRating": "1"
  },
  {%- endif -%}
  "offers": {
    "@type": "AggregateOffer",
    "priceCurrency": {{ cart.currency.iso_code | json }},
    "lowPrice": {{ product.price_min | money_without_currency | json }},
    "highPrice": {{ product.price_max | money_without_currency | json }},
    "offerCount": {{ product.variants.size }},
    "availability": "https://schema.org/{% if product.available %}InStock{% else %}OutOfStock{% endif %}",
    "url": "{{ shop.url }}{{ product.url }}"
  }
}
</script>

Variant-level Offers markup

For products with multiple variants at different prices, individual Offer markup for each variant provides Google with more granular pricing data. This is the approach we use in our product page SEO work:

"offers": [
  {%- for variant in product.variants -%}
  {
    "@type": "Offer",
    "name": {{ variant.title | json }},
    "sku": {{ variant.sku | json }},
    "price": {{ variant.price | money_without_currency | json }},
    "priceCurrency": {{ cart.currency.iso_code | json }},
    "availability": "https://schema.org/{% if variant.available %}InStock{% else %}OutOfStock{% endif %}",
    "url": "{{ shop.url }}{{ variant.url }}",
    "priceValidUntil": "{{ 'now' | date: '%Y' | plus: 1 }}-12-31",
    "itemCondition": "https://schema.org/NewCondition",
    "seller": {
      "@type": "Organization",
      "name": {{ shop.name | json }}
    }
  }{% unless forloop.last %},{% endunless %}
  {%- endfor -%}
]

Review aggregation schema

Star ratings in search results are one of the most powerful rich result types for ecommerce. Shopify’s product metafields for reviews (introduced with the Product Reviews app and supported by Judge.me, Loox, and others) provide the data needed:

{%- if product.metafields.reviews.rating.value -%}
  {%- assign rating = product.metafields.reviews.rating.value -%}
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "{{ rating.rating }}",
    "bestRating": "{{ rating.scale_max }}",
    "worstRating": "{{ rating.scale_min }}",
    "ratingCount": "{{ product.metafields.reviews.rating_count }}"
  },
  "review": [
    {
      "@type": "Review",
      "author": { "@type": "Person", "name": "Verified Buyer" },
      "reviewRating": {
        "@type": "Rating",
        "ratingValue": "{{ rating.rating }}",
        "bestRating": "{{ rating.scale_max }}"
      }
    }
  ],
{%- endif -%}
Product schema with AggregateRating generating star ratings in search
AggregateRating schema enables star ratings in search results. The combination of stars, price, and availability creates compelling search listings.

FAQPage schema on product pages

Adding FAQ content to product pages serves a dual purpose: it answers common customer questions (reducing support queries) and qualifies for FAQ rich results in Google. FAQ schema works particularly well on product pages and collection pages:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {%- for block in section.blocks -%}
      {%- if block.type == 'faq' -%}
      {
        "@type": "Question",
        "name": {{ block.settings.question | json }},
        "acceptedAnswer": {
          "@type": "Answer",
          "text": {{ block.settings.answer | strip_html | json }}
        }
      }{% unless forloop.last %},{% endunless %}
      {%- endif -%}
    {%- endfor -%}
  ]
}
</script>

Proper BreadcrumbList schema replaces the URL in search results with a clean breadcrumb trail. For Shopify, this requires knowing the product’s collection context:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {"@type": "ListItem", "position": 1, "name": "Home", "item": "{{ shop.url }}"},
    {%- if collection -%}
    {"@type": "ListItem", "position": 2, "name": {{ collection.title | json }}, "item": "{{ shop.url }}{{ collection.url }}"},
    {"@type": "ListItem", "position": 3, "name": {{ product.title | json }}, "item": "{{ shop.url }}{{ product.url }}"}
    {%- else -%}
    {"@type": "ListItem", "position": 2, "name": "Products", "item": "{{ shop.url }}/collections/all"},
    {"@type": "ListItem", "position": 3, "name": {{ product.title | json }}, "item": "{{ shop.url }}{{ product.url }}"}
    {%- endif -%}
  ]
}
</script>

Organisation and LocalBusiness schema

Organisation schema helps Google build a knowledge panel for your brand and associates your website with your business entity:

<!-- Add to theme.liquid, output once per page -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "{{ shop.name }}",
  "url": "{{ shop.url }}",
  "logo": "{{ shop.url }}/cdn/shop/files/logo.png",
  "sameAs": [
    "https://www.instagram.com/yourbrand",
    "https://www.facebook.com/yourbrand",
    "https://twitter.com/yourbrand"
  ],
  "contactPoint": {
    "@type": "ContactPoint",
    "contactType": "customer service",
    "email": "{{ shop.email }}",
    "availableLanguage": "English"
  }
}
</script>
Organisation schema enabling Google knowledge panel
Organisation schema helps Google build knowledge panels for branded searches and associate social profiles with your business.

CollectionPage and ItemList markup

Collection pages benefit from ItemList schema, which tells Google about the items within the collection and their order:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "CollectionPage",
  "name": {{ collection.title | json }},
  "description": {{ collection.description | strip_html | truncate: 5000 | json }},
  "url": "{{ shop.url }}{{ collection.url }}",
  "mainEntity": {
    "@type": "ItemList",
    "numberOfItems": {{ collection.products_count }},
    "itemListElement": [
      {%- for product in collection.products limit: 12 -%}
      {
        "@type": "ListItem",
        "position": {{ forloop.index }},
        "url": "{{ shop.url }}{{ product.url }}"
      }{% unless forloop.last %},{% endunless %}
      {%- endfor -%}
    ]
  }
}
</script>

Validation and monitoring

Structured data validation is essential — invalid schema is ignored by Google and provides no benefit. Use multiple validation tools:

  • Google Rich Results Test — tests individual pages for rich result eligibility. The most authoritative tool.
  • Google Search Console — the Enhancements section reports structured data status across your entire site, including errors and warnings.
  • Schema.org Validator — validates syntax against the Schema.org specification.
  • Lighthouse — includes structured data validation as part of its SEO audit.

Common structured data errors

  • Missing required properties — Product schema requires name, image, and at least one Offer with price and priceCurrency.
  • Price formatting — prices must be numeric values without currency symbols. Use money_without_currency in Liquid.
  • Empty values — do not include properties with blank values. Use Liquid conditionals to omit empty fields.
  • Invalid URLs — all URLs must be absolute (starting with https://), not relative paths.
  • Mismatched data — the structured data must match the visible page content. A price in the schema that differs from the displayed price will be flagged.
  • Self-serving reviews — review schema must reflect genuine customer reviews. Fabricated reviews violate Google’s guidelines.
Common structured data validation errors and their fixes
Validate structured data on every template type using Google’s Rich Results Test. Fix errors before they propagate across your entire catalogue.

Advanced structured data is one of the highest-ROI SEO activities for Shopify stores. The implementation effort is modest — a few hours of Liquid development — and the impact on click-through rates and organic traffic is measurable and lasting. If you need help implementing comprehensive structured data on your Shopify store, get in touch — it is a core part of our SEO and Shopify development work.