Why your Shopify products don't show prices and stars in Google (and how to fix it)
Search for one of your products in Google. Then search for a competitor's.
If theirs shows a price, a star rating and "In stock" right there in the results, and yours is a plain blue link, you're losing the click before anyone visits either site. Same product, same demand, different structured data.
Here is the difference, in the results page itself:
yourstore.com › products
Competition Olympic Barbell 20kg
Home / Barbells / Competition Olympic Barbell. Add to cart. Size. 24 reviews...
competitor.com › products
Competition Olympic Barbell 20kg
★★★★★ 4.8 (96) · £250.00 · In stock
IWF-spec 20kg barbell, 28mm shaft, dual knurl marks. Free UK delivery...
Two results for the same product. The one on the right earns more clicks before anyone has visited either site, and it does it with markup, not a better product.
This is one of the most common, most fixable SEO gaps on Shopify, and it has nothing to do with how good your products are. Here's what's happening and how to sort it.
What product schema actually is
Structured data (also called schema, or JSON-LD) is a block of machine-readable code in the page's <head> that labels what the page is. For a product it says, in a format Google trusts: this is a Product, it costs £250, it has a 4.8 rating from 96 reviews, it's in stock.
Google uses that to build a rich result: the search listing with the price, stars and availability. You can't earn that listing by putting the price in your page text; Google wants the labelled version. No schema, no rich result, lower click-through, fewer visits.
How to check yours in two minutes
- Open a product page, right-click, View Page Source, and search (Ctrl/Cmd-F) for
Product. If you see"@type":"Product"you have something. - Paste the URL into Google's free Rich Results Test. It tells you whether the page is eligible for a product rich result, and lists any errors or missing recommended fields.
A page in good shape comes back like this:
Product snippets and Merchant listings: 1 valid item detected, no errors.
If it finds nothing, or flags missing offers, price or availability, that's your gap.
Would you rather check your store than read a checklist? AuditTag scans your product pages and flags the ones with no product schema, or schema that is not valid JSON, in about a minute. Run a free audit →
Three schema gaps to check on a Shopify store
1. No product schema at all. Some themes and older setups emit none. The Rich Results Test finds nothing. This is the big one, and the biggest opportunity.
2. Reviews on the page but not in the schema. Your reviews app (Judge.me, Loox, Okendo, Yotpo…) shows stars on the storefront, but those stars aren't in the structured data, so they never reach the results page. All that social proof stops at the browser. Most review apps have a setting to output AggregateRating schema, so turn it on and re-test.
3. Partial schema. The Product is there but offers, price, priceCurrency or availability are missing, so Google validates the type but won't show the rich result. The Rich Results Test will name exactly which recommended fields are absent.
A nuance most SEO tools get wrong: ProductGroup is fine
If your products have variants (sizes, colours, weights), Shopify often expresses them as a ProductGroup with each variant nested inside a hasVariant array, like this:
{
"@context": "https://schema.org",
"@type": "ProductGroup",
"name": "Competition Olympic Barbell",
"hasVariant": [
{ "@type": "Product", "name": "15kg", "offers": { "@type": "Offer", "price": "220.00", "priceCurrency": "GBP", "availability": "https://schema.org/InStock" } },
{ "@type": "Product", "name": "20kg", "offers": { "@type": "Offer", "price": "250.00", "priceCurrency": "GBP" } }
]
}
This is valid, Google-recommended markup for variant products: the Products live inside the group. Some SEO checkers only look at the top level, see ProductGroup instead of Product, and wrongly tell you your product schema is "missing." (We know, because our own audit did exactly that once, on a store whose markup was perfect, and we fixed it.) So before you rebuild anything: if the Rich Results Test is happy, your schema is fine, whatever a scoring badge says.
How to fix it on Shopify (where the code actually lives)
If you have partial or no schema: the durable fix is one correct JSON-LD block per product, reflecting what's already true on the page, never invented. The <head> isn't editable from the admin product fields, so on Shopify this lives in the theme, not the product editor. In practice that means a snippet (say snippets/product-schema.liquid) rendered into the head from theme.liquid or the product template.
Build the values from Liquid objects rather than typing them in, so they stay correct as prices and stock change. Shopify exposes exactly what you need: {{ product.selected_or_first_available_variant.price | money_without_currency }} for the price, {{ cart.currency.iso_code }} or {{ shop.currency }} for the currency, {{ product.selected_or_first_available_variant.available }} for stock, and product.metafields for anything your reviews app stores. Add it to a duplicate theme, test with the Rich Results Test, and publish when it's clean.
If it's your reviews: enable schema output in your reviews app, and check the theme isn't also emitting its own review markup (see the pitfalls below).
Either way, re-run the Rich Results Test after, and expect the rich result to appear within a crawl or two, not instantly, but soon.
Common pitfalls that quietly kill a rich result
These are the ones that pass a glance but fail Google, and they're specific to how Shopify is usually set up:
- Two
Productblocks that disagree. If your theme emits product schema and your reviews app injects its own, you can end up with two@type: Productblocks carrying different prices or ratings. Google sees the conflict and often drops the rich result for the page entirely. Pick one source of truth: usually the theme snippet for the product, with the reviews app contributing only theAggregateRating. - Multi-currency and Shopify Markets. If shoppers can switch currency, a hardcoded
"priceCurrency": "GBP"in a static snippet will mismatch the price a visitor (or Googlebot in another region) actually sees. Drive the currency from Liquid (cart.currency.iso_code) so the label and the number always agree. - Hardcoded prices vs variant switching. When a shopper picks a different variant, JavaScript updates the visible price, but a price baked into the JSON-LD at page load doesn't move with it. Render the price from the selected variant, and let the
ProductGroup/hasVariantstructure carry each variant's own offer.
Check it site-wide in Search Console
The Rich Results Test checks one URL, live. To see the whole catalogue over time, open Google Search Console and look at the Product snippets and Merchant listings reports under Enhancements. They show how many of your pages Google considers valid, how many are invalid and why, and whether a change you shipped actually moved the numbers. One is your spot-check; the other is your dashboard.
What AuditTag checks on your public pages
- Product pages with no Product or ProductGroup markup
- Structured data that is not valid JSON
What this doesn't prove
The audit checks that product markup exists and parses. It does not yet check individual fields such as price or availability, so use Google's Rich Results Test for those. Even valid markup only makes a page eligible for price and review details in Google. It does not guarantee them: Google decides what to show. The audit reads your public pages, so markup added only by JavaScript after load may not be seen.
Checking one product is easy. Checking 500 variants isn't.
The Rich Results Test takes two minutes per URL. A 500-product catalogue, each with its own variants, is impossible to check by hand, which is exactly the point AuditTag exists at. The free audit counts the product pages with no product schema or broken JSON, shows the worst of them in full, and correctly ignores the ones that already have valid ProductGroup markup. No app, no access to your store, and you review every change before it goes live. If you want it done, the fix pack hands you the corrected theme snippet to paste in yourself.
Start by checking one product in the Rich Results Test. Five minutes now can be the difference between a plain link and a listing that sells. You can also read a whole sample fix pack to see exactly what a corrected snippet looks like before you spend anything.
Keep reading
- Shopify meta descriptions: why Google ignores yours
- Alt text at scale on Shopify, without touching 300 products one by one
- See the sample fix pack: the entire deliverable, free to download