Skip to main content
Private betaThe Shopify app that gets your products recommended by AI.Shopify app: get recommended by AII want in
Critical Reviews

AggregateRating: Make Reviews AI-Readable

Updated Up to date
#aggregate-rating#reviews#schema-org#crawlers#llm
Share
This article includes a quiz, test your knowledge at the end! Jump to quiz

The problem: your JavaScript-loaded reviews are invisible to most AI

Customer reviews are one of the strongest trust signals for AI shopping agents. Yet on most Shopify stores, the stars shown to human visitors are never read by ChatGPT, Perplexity, Claude, Mistral Le Chat or most other LLMs.

The reason is technical. Loox, Judge.me, Yotpo, Reviews.io and the majority of review apps inject their AggregateRating client-side, via JavaScript, after the page loads. AI crawlers only retrieve the initial HTML returned by the server : they don’t execute JavaScript. In that source HTML, there are no stars, no average rating, no review count.

A store with 5,213 reviews and a 4.8/5 rating is therefore presented to AI as a store with zero reviews, zero stars.

The simple test to check your store

From a terminal, run this command replacing the URL with one of your product pages:

curl -A "GPTBot" -sL "https://your-store.com/products/example" | grep -i "aggregaterating"

If the command returns nothing, your AggregateRating isn’t in the native HTML. It’s injected via JavaScript, therefore invisible to GPTBot and all AI crawlers that work the same way.

You can validate with two official tools:

Why AI crawlers don’t render JavaScript

The main AI crawlers operate in simple HTTP mode, without a headless browser. They send a request, read the received HTML, and move to the next document. This isn’t trivial: it’s documented by the model providers, measured at scale, and cross-referenced between studies.

Native HTML vs JavaScript comparison: reviews in server-side JSON-LD are visible to GPTBot, ClaudeBot, PerplexityBot, while JavaScript-loaded reviews are invisible
Figure 1 : What AI crawlers see: the server-side HTML vs. the DOM after JavaScript execution

AI crawlers and JavaScript rendering matrix

CrawlerOperatorRenders JavaScript?Source
GPTBotOpenAINoOpenAI docs, Vercel 500M+ req
OAI-SearchBotOpenAINo (not explicitly documented)OpenAI bots
ChatGPT-UserOpenAINoSame
ClaudeBotAnthropicNo (“don’t rely on JavaScript”)Anthropic privacy
Claude-SearchBotAnthropicNoSame
PerplexityBotPerplexityNoPerplexity crawlers
Meta-ExternalAgentMetaNoMeta webmasters
CCBotCommon CrawlNo (official)Common Crawl FAQ
MistralAI-UserMistralBrowser-session-like, does not respect robots.txtdocs.mistral.ai/robots
Google-ExtendedGoogleYes (reuses Googlebot’s Web Rendering Service)Google crawlers
Applebot / Applebot-ExtendedAppleYesApple support
BingbotMicrosoftYes, partial (evergreen via Edge)Bing blog

Out of 12 major crawlers, only Googlebot, Bingbot and Applebot reliably render JavaScript. All others read only the initial HTML.

What it means for your store

If your AggregateRating is loaded via JavaScript and you want to appear in:

  • ChatGPT text answers (via Bing + GPTBot/OAI-SearchBot): invisible
  • Claude citations (via ClaudeBot): invisible
  • Perplexity text answers (via PerplexityBot): invisible
  • Mistral Le Chat: invisible
  • Meta AI in WhatsApp, Instagram and Facebook: invisible
  • Grok on X, DeepSeek, Qwen: invisible
  • Custom MCP agents (Zapier, n8n, Make) proliferating in 2026: invisible
  • Browser agents that scrape page HTML: invisible

The Google Merchant Center feed, detailed below, covers part of the problem : but only for 2 AI surfaces out of more than 12.

Why Shopify doesn’t natively expose AggregateRating

The official Liquid filter {{ product | structured_data }} produces a minimal Product schema containing @context, @id, @type, brand, category, description, image, name, offers and url. It does not include aggregateRating, review or rating, as documented on the Shopify reference.

The reason was given publicly by a Dawn theme maintainer in GitHub issue #3535:

“We are only returning fields in the structured data that come from concrete data, not sourced from metafields.”

Reviews live in third-party app metafields (Loox, Judge.me, Yotpo, etc.). Shopify therefore doesn’t surface them in its default schema. On an official Online Store 2.0 theme (Dawn, Craft, Sense, Studio, Crave, Taste, Ride, Origin, Colorblock, Publish), the server-side HTML of a product page contains no review data. Everything goes through the apps’ JS widgets.

Detailed analysis of the 7 main Shopify review apps

Loox

Widget rendering: app block via Shopify Online Store 2.0, loox core script executed client-side.

AggregateRating JSON-LD: Loox announces automatic generation of Product, Offer and AggregateRating JSON-LD (Loox rich results blog). Public documentation doesn’t explicitly specify whether this injection is server-side via a theme app extension Liquid block, or client-side via script : in practice, it operates as a JS injection into the DOM.

Google Merchant Center syndication: available starting on the Scale plan, requires at minimum 50 published reviews, syndicates all verified reviews without filter (Loox GMC help).

Judge.me

Widget rendering: Liquid template <div class="jdgm-widget jdgm-preview-badge" data-id="{{ product.id }}">{{ product.metafields.judgeme.badge }}</div> hydrated by widget.js client-side (Judge.me Liquid code).

JSON-LD rich snippets: togglable in Settings → Advanced → Rich Snippets. Judge.me recommends enabling JSON-LD and disabling microdata to avoid duplicates.

Google Merchant Center syndication: manual setup via Settings → Google and SEO → Google Shopping. Requires a minimum of 50 reviews, product identifiers (GTIN preferred), and Google manual approval of 2 to 4 weeks (Judge.me GMC help).

Yotpo

Widget rendering: Yotpo admits in its own documentation: “Yotpo’s JavaScript automatically loads on your product pages, detects the product, fetches the latest review data, and injects the perfect JSON-LD schema into the page’s code” (Yotpo blog). This is client-side injection by construction.

Google Merchant Center syndication: available on Starter, Pro, Premium, Enterprise (not on Free). Requires 50 total reviews and 3 reviews minimum per product. UGC photos restricted to Premium and Enterprise (Yotpo GMC syndication).

Stamped

Widget rendering: client-side via <script> before </body> (Stamped install).

AggregateRating JSON-LD: Stamped provides a JSON-LD block to manually paste into product.liquid, which reads Stamped metafields and produces server-side AggregateRating (Stamped rich snippets). Without this manual installation, nothing appears server-side.

Reviews.io

Default rendering: 3 <script> before </body> + a <div data-sku> placeholder (Reviews.io rich snippets). Client-side injection. Rich snippets limited to Start-Up, Grow, Plus, Launch, Launch Plus plans.

Okendo

Widget rendering: server-side pre-rendering per Okendo marketing docs (site speed reviews).

AggregateRating JSON-LD: Okendo is the only app that officially documents server-side injection via a Liquid snippet. The official guide asks to create snippets/okendo-reviews-json-ld.liquid, include {% render 'okendo-reviews-json-ld' %} in theme.liquid, and read the metafields product.metafields.okendo.summaryData.reviewAverageValue and product.metafields.okendo.summaryData.reviewCount (Okendo rich snippets).

It’s currently the only app on the Shopify market with a clearly documented native SSR path.

Opinew

Hybrid approach: Opinew provides a snippet that reads server-side metafields (product.metafields.opinew_metafields.reviews_count, .reviews_rating), then uses a client-side script to create a <script type="application/ld+json"> element and inject it into the DOM after load (Opinew rich snippets).

Opinew also integrates with third-party SEO apps like JSON-LD for SEO, Yoast SEO and SEO Booster, which read Opinew metafields server-side and emit JSON-LD in native HTML. This is the path that guarantees AI visibility with Opinew.

Summary: server-side AggregateRating per app

AppWidgetDefault JSON-LDDocumented SSR path
LooxClient-sideJS injectionNot publicly documented
Judge.meClient-sideTogglable option, JS injectionNot publicly documented
YotpoClient-sideJS injection (Yotpo-admitted)No
StampedClient-sideNo (manual install required)Yes, manual
Reviews.ioClient-sideClient scripts by defaultNot documented
OkendoServer-sideNative Liquid snippetYes, documented
OpinewClient-sideJS by default, or third-party SEO appYes, via third-party app

The Google Merchant Center feed: a partial solution

All major review apps offer syndication to Google Merchant Center. This path feeds the ChatGPT product carousel (83% of carousels come from Google Shopping per the Peec AI study covered by Search Engine Land) and Perplexity’s carousel.

What the GMC feed covers

  • The ChatGPT product carousel (via Google Shopping)
  • The Perplexity product carousel if the merchant is enrolled in the Perplexity Merchant Program
  • Classic Google Shopping
  • Partially Google AI Mode carousels

What the GMC feed doesn’t cover

  • ChatGPT text answers and citations (Bing crawler pipeline, 87% of SearchGPT citations match Bing top 20 per Seer Interactive)
  • Perplexity text answers (PerplexityBot crawler on HTML)
  • Claude, Mistral Le Chat, Meta AI, Grok, DeepSeek, Qwen, Pi, Cohere (all crawler-only)
  • Citations in Google AI Overviews
  • Custom MCP agents (Zapier, n8n, Make, ChatGPT Apps)
  • Live browser agents (Comet, Claude Computer Use, Browser Use)

For these surfaces, AggregateRating must be present in native HTML, as JSON-LD or microdata, extractable without JavaScript execution.

GMC feed setup: not default, not automatic

None of the 3 main apps (Loox, Judge.me, Yotpo) enable GMC syndication by default. Each requires a manual toggle, specific prerequisites, and Google validation over several weeks. See the table above for requirements per app.

The fix: expose AggregateRating in server-side HTML

Even with a client-side widget, all review apps write data to Shopify metafields accessible server-side. These metafields are read at Liquid render time, which allows emitting JSON-LD directly in the initial HTML.

Here’s a Liquid snippet example to place in sections/main-product.liquid or templates/product.liquid:

{% if product.metafields.reviews.rating_count and product.metafields.reviews.rating_count != "0" %}
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "@id": "{{ shop.url }}{{ product.url }}#product",
  "name": {{ product.title | json }},
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "{{ product.metafields.reviews.rating.value }}",
    "reviewCount": "{{ product.metafields.reviews.rating_count }}",
    "bestRating": "5",
    "worstRating": "1"
  }
}
</script>
{% endif %}

The namespace product.metafields.reviews.* is the historical one of the official Product Reviews by Shopify app (now deprecated). For other apps, adapt the namespace:

AppNamespace to use
Judge.meproduct.metafields.judgeme.badge (contains HTML) + exposed numeric metafields
Okendoproduct.metafields.okendo.summaryData.reviewAverageValue and .reviewCount
Opinewproduct.metafields.opinew_metafields.reviews_rating and .reviews_count
Yotpoproduct.metafields.yotpo.reviews_average and .reviews_count (community-confirmed, not publicly documented)

Rules for valid JSON-LD

Per the official Google spec:

  • ratingValue is required
  • At least one of ratingCount or reviewCount is required
  • ratingValue must be between worstRating and bestRating (default 1 and 5)
  • Don’t emit AggregateRating if the product has 0 reviews (triggers Search Console warnings)

Final validation

After adding the snippet, validate through 3 channels:

  1. curl -A "GPTBot" -sL "PRODUCT-URL" | grep aggregaterating : must return a line with JSON-LD
  2. Google Rich Results Test : must display valid “Review snippets”
  3. Schema.org Validator : must validate the structure

Context data: how many AI read your HTML?

Vercel, which operates a CDN measuring AI crawler traffic, published in 2025 an analysis of over 500 million GPTBot requests and 370 million ClaudeBot requests per month. On this sample, neither crawler executes JavaScript (Vercel AI crawler).

Yext analyzed 6.8 million AI citations and identified that 86% of AI citations come from brand-managed sources (own site, feeds, structured FAQs) (Yext press release). Investing in your own HTML is therefore more effective than relying exclusively on third-party sources.


Ready to check your store? Run a free GEO audit →

Frequently Asked Questions

Why are my Loox, Judge.me or Yotpo reviews invisible to ChatGPT?
These apps inject their stars and AggregateRating via JavaScript after page load. AI crawlers like GPTBot, ClaudeBot, PerplexityBot, Meta-ExternalAgent and CCBot don't execute JavaScript. They only see the initial HTML sent by the server, which contains no review data.
Doesn't the Google Merchant Center feed solve the problem?
Only partially. The GMC feed powers the ChatGPT product carousel (83% of carousels come from Google Shopping) and Perplexity's carousel. But it doesn't cover ChatGPT text answers, citations, Claude, Mistral Le Chat, Meta AI, Grok, DeepSeek, or MCP and browser agents. For those surfaces, HTML AggregateRating is essential.
Which review app exposes AggregateRating as native HTML on Shopify?
Okendo is the only app that publicly documents a server-side injection via a Liquid snippet. Stamped provides JSON-LD but requires manual installation in the theme. Loox, Judge.me, Yotpo, Reviews.io inject AggregateRating client-side by default. Opinew is hybrid.
Does Shopify expose AggregateRating natively in its schema?
No. The Liquid filter {{ product | structured_data }} generates Product, Offer, Brand and Image, but deliberately omits aggregateRating and review. The official reason from the Dawn repo: Shopify only surfaces concrete catalog data, not data from third-party app metafields.
How do I test if my AggregateRating is read by AI crawlers?
Run curl -A 'GPTBot' -sL 'https://your-store.com/products/slug' | grep -i aggregaterating. If nothing matches, your reviews are invisible. Then validate with Google Rich Results Test and schema.org Validator.
Which schema.org should I use for reviews?
The AggregateRating type with at minimum ratingValue plus one of ratingCount or reviewCount. The ratingValue must be between bestRating (default 5) and worstRating (default 1). Emit it only if the product has at least 1 real review.
🧠 Test your knowledge
1 / 5