Your Shopify Store's Schema Is Fighting Itself
Patrick ScottShare
Most Shopify store owners assume structured data is handled. The theme outputs it. The SEO app outputs it. The review app outputs it.
That's the problem. They all output it.
When your theme and your apps each inject their own Product JSON-LD into the same page, Google doesn't get more information — it gets conflicting information. And when Google can't tell which version of your product data is authoritative, the most common outcome is that it trusts neither. Your pricing, availability, and star ratings can quietly drop out of search results while every individual tool reports that everything is fine.

This article covers the structured data conflicts we find most often in Shopify stores, why they happen, and how to check your own store today. No ranking promises here — structured data is about eligibility and how clearly search systems understand your store, not a shortcut up the results page.
The core conflict: too many cooks in the page source
Shopify themes like Dawn and Horizon ship with built-in structured data — usually a Product block rendered from the theme's structured data snippet or main product section. That's good. It's maintained by Shopify and stays in sync with your live prices and inventory.
Then a store installs an SEO app (Avada, TinySEO, JSON-LD for SEO) or a review app (Judge.me, Stamped.io), and that app injects its own Product block. Now the same page carries two — sometimes three — competing descriptions of the same product.

What Google does with duplicates is unpredictable by design. Documented outcomes include:
- Google merging entities that share an
@id, producing "duplicate field" errors in Merchant Center (the "Duplicate field 'brand'" error is a classic) - Search Console Enhancements errors that seem to come from nowhere
- Suppressed rich results while both the theme and the app individually validate clean
The fix is a decision, not a plugin: pick one authoritative source of Product schema per page and disable the other. If you keep the app's schema, disable the theme's output. If you keep the theme's, turn off schema injection in the app's settings. What you can't do is keep both.
The @types that don't exist
A surprising amount of Shopify schema in the wild uses types that were never part of the Schema.org vocabulary at all. We regularly see:
-
ShopifyProduct,ShopifyStore,ShopifyCollection -
ECommerceStore,eShop,OnlineSeller -
ProductVariant(plausible-sounding, but not real — variants are modeled asProductnodes inside aProductGroup)

Schema.org contains over 800 types. None of them are platform-branded. "Shopify" is where your store lives; it is not a semantic category. Any JSON-LD block using an invented @type is structurally invalid, and Google's parsers ignore it completely. You get the page weight of the markup with none of the benefit.
These usually come from older third-party apps, copy-pasted tutorial code, or auto-generated snippets. If a scan of your page source turns one up, the markup it belongs to is doing nothing — and should be replaced with the real type it was reaching for.
The identity question: OnlineStore, not LocalBusiness
If your store has no physical storefront, Google's own guidance is explicit: use the OnlineStore type — a subtype of Organization built for exactly this case.
What you should not do is mark an online-only store as a LocalBusiness. That type asserts a physical location customers can visit, and using it without a verified, visible address on the page is a policy violation, not a gray area. It can also seed incorrect Knowledge Panel data that's painful to unwind later.
Older themes and apps injected LocalBusiness by default, so plenty of purely online stores are still carrying it. The rule of thumb: if there's no address a customer could drive to displayed on your site, there should be no LocalBusiness in your markup.
(If you run a genuine hybrid — online store plus a retail location — you can model both, but they should be distinct, properly linked entities. That's a design decision, not a checkbox.)
The visibility rule: if users can't see it, don't mark it up
Google's requirement for review markup is blunt: the review content you mark up must be readily visible to users on that page.
This is where review apps get stores in trouble. The common failure pattern:
-
aggregateRatinginjected into JSON-LD on products with zero collected reviews - Star ratings present in the markup while the review widget is hidden, lazy-loaded below the fold, or rendered only after crawl time
-
Reviewobjects with author names that appear nowhere in the visible page

Each of these is a mismatch between what your code claims and what your page shows — and that mismatch is grounds for Google to suppress the rich result or, in worse cases, take manual action against the site.
One genuinely useful clarification, because it's widely misunderstood: product reviews on your own product pages are allowed. The "self-serving review" prohibition applies to reviews about your business (Organization/LocalBusiness markup) hosted on your own site. Customer reviews of a specific product, visible on that product's page, are fully eligible for review rich results. The line is between reviewing your company and your customers reviewing your products.
Collection pages marked as products
Some older themes and apps apply Product markup — sometimes with an Offer and a price — to /collections/ pages. Google's guidelines are unambiguous: product rich results only support pages focused on a single product or its variants. Marking an entire category as one product is a violation that can suppress product rich results across your whole store, not just the offending page.
The correct model for a collection page is CollectionPage with an ItemList as its main entity, plus a BreadcrumbList. Worth knowing before anyone sells you on it: there is no dedicated rich result for collection pages, and ItemList does not trigger product rich results. It's clean structural context — valuable for how systems parse your site, not a visual SERP feature.
The small required fields that break everything
Two fields cause an outsized share of Merchant Center and Search Console errors:
priceCurrency. Required on every Offer. Some theme versions have shipped "price": "29.99" with no currency code — which fails validation for merchant listings.
availability. Should use the full schema.org URI (https://schema.org/InStock), not a bare string.
And one architectural gotcha for stores with variants: Shopify's structured_data filter historically generated identical @id values for all variants, which caused Google to merge them into a single entity and index only the first. Shopify shipped a fix, but the filter still caps output at 250 variants — an open limitation for large catalogs. If you sell products with big variant matrices, this is worth an explicit check.
How to audit your own store in 15 minutes
-
View source on a product page and search for
application/ld+json. Count the blocks. More than oneProductblock is your first finding. - Run the page through Google's Rich Results Test. Note errors vs. warnings — errors block eligibility, warnings limit enhancements.
-
Check a collection page the same way. Any
Product@type at the top level of a/collections/URL is a stop-and-fix. -
Look at a product with no reviews. If the JSON-LD contains
aggregateRatinganyway, your review app is writing checks your page can't cash. - Check Search Console → Enhancements for product, merchant listing, and breadcrumb issues you didn't know were accumulating.
None of this requires code changes to diagnose. It requires knowing what to look for — which is exactly the gap most "install and forget" schema apps create.
What fixing this actually gets you
Let's be precise, because this space is full of overpromising:
- Valid, conflict-free structured data makes your store eligible for rich results — pricing, availability, ratings in search listings. Google controls display at its discretion; nobody can guarantee stars.
- Clean markup means Merchant Center and Search Console stop generating errors, and your product data flows correctly into Google's shopping surfaces.
- As AI-powered search leans harder on structured data as a citation and understanding signal, unambiguous markup is increasingly how machines decide what your store is.
What it doesn't do is directly move keyword rankings. Anyone who promises that is selling you something schema can't deliver.
Find out what's actually in your page source
If you'd rather not spelunk through JSON-LD blocks yourself, that's what the free E.V.I.L. Scan is for — we read what your pages actually output, flag the conflicts, and tell you in plain language which source is fighting which. No pitch, just findings.