Skip to content
Published Authored byBilly Reiner

Schema · How-to

Shopify AggregateRating schema

AggregateRating is the Schema.org type for an average rating based on multiple individual ratings or reviews1. On a Shopify PDP, it lives as a sub-object on Product. Properties: ratingValue, ratingCount, reviewCount, bestRating, worstRating. The catch: Google's self-serving rule states a business cannot aggregate ratings about itself for star snippet eligibility2. Reviews collected on the merchant's own Shopify store, including via Shopify's first-party Product Reviews app, do not earn the star snippet.

What this means in practice on Shopify: review apps that route reviews through their own third-party platform (Yotpo, Stamped.io, Judge.me, Reviews.io, Okendo) emit AggregateRating that Google treats as independent. The Shopify Product Reviews app and any custom in-house review system are self-serving. The schema is structurally identical; the eligibility differs.

What AggregateRating is

Per Schema.org v30.0, AggregateRating is 'the average rating based on multiple ratings or reviews.' Type hierarchy: Thing > Intangible > Rating > AggregateRating. The required-by-Google fields are ratingValue, ratingCount or reviewCount (at least one), itemReviewed (handled implicitly when AggregateRating is a sub-object on Product). Recommended: bestRating and worstRating to disambiguate the rating scale.

Mental model: AggregateRating is the summary statistic; Review is the individual data point. A Shopify product with 47 reviews averaging 4.8 stars has one AggregateRating object (the summary) and up to 47 Review objects (each individual rating). Most Shopify schema work emits AggregateRating only — Review objects are heavier to emit and rarely needed for the rich snippet, which uses the aggregate.

The self-serving review rule on Shopify

Google's Review snippet documentation states 'don't aggregate ratings or reviews that are self-serving.' An entity collecting and displaying reviews about itself on its own site is self-serving. Reviews about an entity collected and verified by an independent third-party platform are not. The structural JSON-LD is identical in both cases; eligibility for the star snippet depends on the source. This matters on Shopify because Shopify's first-party Product Reviews app, and most simple in-house review systems, are self-serving by Google's definition.

Shopify review apps that emit AggregateRating cleanly

The 2026 Shopify review-app market splits into three groups. (1) Third-party platforms that emit AggregateRating in their app block: Yotpo, Stamped.io, Judge.me, Reviews.io, Okendo, Loox. (2) First-party Shopify: Shopify Product Reviews (self-serving), Shop reviews from the Shop channel. (3) Custom in-house systems built on Shopify metafields or metaobjects, which require the merchant to author AggregateRating JSON-LD by hand.

Audit step before authoring: install the review app in a staging store, view source on a PDP with reviews, find-on-page for AggregateRating. If the app emits its own block, you do not need to author one. If it doesn't, or if you want to consolidate multiple review sources into one AggregateRating on Product, author the block via Liquid using the app's metafields or metaobject API.

AggregateRating fields

The properties that matter: ratingValue (Number/Text — the average, e.g. 4.8), ratingCount (Integer — total ratings received), reviewCount (Integer — total reviews received; can equal ratingCount), bestRating (Number/Text — the highest possible, e.g. 5), worstRating (Number/Text — the lowest possible, e.g. 1).

  • ratingValue — required. The average rating. Typical scale: 1–5.
  • ratingCount OR reviewCount — at least one required by Google.
  • bestRating — recommended. Default is 5 if omitted, but emitting it removes ambiguity.
  • worstRating — recommended. Default is 1 if omitted.
  • itemReviewed — required when AggregateRating is top-level; implicit when nested as a sub-object of Product.

JSON-LD example — AggregateRating from a third-party review app

The block below shows AggregateRating inside a Shopify Product block, using Liquid metafields from a third-party review platform (Judge.me's metafield namespace shown — adjust per the actual app in use).

JSON-LD AggregateRating inside Product, Liquid-driven from review-app metafields
 {%- if product.metafields.reviews.rating_value -%} "aggregateRating": { "@type": "AggregateRating", "ratingValue": "{{ product.metafields.reviews.rating_value }}", "reviewCount": "{{ product.metafields.reviews.rating_count }}", "bestRating": "5", "worstRating": "1" }, {%- endif -%} 

Validation

Rich Results Test against a PDP with AggregateRating should report Product detected, AggregateRating parsed, and (if the reviews are independent third-party) eligibility for the review snippet. If reviews are self-serving, the test typically reports 'Either the rating is not from an aggregate source, or the page is the subject of the review' — informational, not an error. The schema is valid; the snippet just won't render. For AI engine citation, that's fine; the markup still helps.

A subtle gotcha: the Rich Results Test does not always reliably detect self-servingness automatically — sometimes it eligibility-passes the markup and then Google's main index demotes the snippet later. The honest test for self-servingness is the source, not the validator: if the reviews live on the merchant's own Shopify storefront, they're self-serving regardless of whether the validator complains.

Shopify gotchas on AggregateRating

Four gotchas. First: emitting AggregateRating with ratingValue '0' and reviewCount '0' on products that haven't been reviewed (branch on the metafield, see above). Second: assuming Shopify Product Reviews app reviews are eligible for stars (they are not — self-serving). Third: emitting AggregateRating both from your manual block AND from a review-app's auto-emitted block, producing duplicate AggregateRating on one Product. Fourth: hard-coding bestRating as 10 when the app uses a 1–5 scale, causing 4.8 to render as '4.8 out of 10'.

A fifth gotcha specific to multi-locale Shopify stores: ratingValue should be emitted with a period decimal separator (4.8), not a comma (4,8). Liquid output of a metafield in some locales serialises with the locale's decimal separator — if your store ships AggregateRating as '4,8', wrap the value in | replace: ',', '.'.