Quick answer: Most Shopify stores already emit some structured data — the problem is that it is wrong, not missing. Themes ship partial Product markup, apps inject a second copy, and the two disagree. This guide is about auditing what your store already outputs and fixing the specific errors Google reports. If you are adding markup from scratch, start with the Shopify schema markup guide instead; this page picks up after markup exists.

Structured data fails quietly. Nothing breaks on the page, the theme still renders, and the only symptom is that rich results never appear — or appear once and vanish weeks later. This guide covers how to see what your store actually emits, the five errors that account for most Shopify failures, and how to keep markup correct as the catalogue changes.

First, see what your store actually outputs

Do not trust the app list. Open a product page, view source, and search for application/ld+json. You will usually find more than one block: the theme emits one, and any SEO or reviews app emits another. Count them before changing anything.

Then run the page through Google's Rich Results Test. It reports per-type: what it detected, which fields are missing, and which are invalid. Warnings are optional fields; errors make the page ineligible for the rich result entirely.

The Search Console Enhancements reports are the fleet view. They lag by days but they cover every indexed URL rather than the one you happened to test, and they show whether an error is spreading.

The five errors that account for most Shopify failures

Two Product blocks that disagree. The theme emits a Product with one price; a reviews app emits another with a rating. Google picks one, usually not the one you want. Fix by removing one source, not by adding a third.

Price and availability drift. Markup is generated at page render but cached, or hardcoded during a theme edit. A product goes out of stock and the markup still says InStock. This is the fastest way to get merchant listings suppressed, because it is checked against your storefront.

AggregateRating with no visible reviews. Google requires the rating to be visible on the page it is marked up on. Markup that carries a rating the shopper cannot see is a spam signal, and it is the single most common cause of a manual action on a Shopify store.

Missing offers entirely. A Product node with a name, description and brand but no offers is not eligible for a product rich result at all. It validates without errors and does nothing.

Escaped or truncated JSON. Markup injected through a theme setting or a metafield gets HTML-escaped, so " becomes " and the block stops parsing. It fails silently — the Rich Results Test simply reports no structured data found.

Fixing without making it worse

Change one source at a time and re-test. Two simultaneous edits to two emitters is how stores end up with three Product blocks.

Match markup to the visible page every time. If the page does not show a price, do not mark one up. The rule Google enforces is not "is the data true" but "can a shopper see it".

Re-test after theme updates. A theme update replaces template files, and hand-edited JSON-LD in product.liquid is overwritten without warning. If your markup lives in theme files, it is a maintenance commitment; if it lives in an app or a metafield, it survives.

Keeping it correct as the catalogue changes

A store with 40 products can be validated by hand. A store with 4,000 cannot, and the failure mode is that a subset of pages breaks — a product type with no brand, a collection with no image — while the ones you spot-check stay fine.

Store Size Validation Approach Risk
40 products Validated by hand All pages checked; errors likely caught
4,000 products Cannot be validated by hand; spot-check only Subset of pages breaks (e.g., missing brand or image) while spot-checked pages stay fine

That is the case for generating markup from live product data rather than templating it: the values come from the same source the storefront renders, so they cannot drift apart. RankEngine does this and re-validates on a schedule, which is the part that matters more than the initial injection.

Where to go next