What it means
Many Shopify themes publish it, but it's easy to lose: an older or heavily customised theme may never have had it, a theme edit can delete the snippet, a broken value can make the whole block unparseable, and an app may inject it with JavaScript so it isn't in the HTML a crawler first downloads.
Test it free: Paste a product URL and see the structured data in its HTML, whether it only appears after JavaScript, and what's missing.
Open the structured data tester →Example diagnosis
What the structured data tester found on one product page
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"Organization","name":"Harbor & Pine", ...}
</script>
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BreadcrumbList", ...}
</script>
<!-- no Product or ProductGroup block in the downloaded HTML -->
<script src="https://cdn.example-reviews-app.com/schema.js" defer></script>
The page has structured data, just not about the product: an Organization block from the theme's header and a BreadcrumbList. Neither tells a crawler the price, the currency or whether the item is in stock.
The reviews app loads a script that adds a Product block after the page runs JavaScript. Google can render it later, but its documentation warns that markup generated with JavaScript makes Shopping crawls less frequent and less reliable. Crawlers that don't run JavaScript never see it.
Symptoms
- Google's Rich Results Test or the structured data tester finds no Product or ProductGroup item on a product URL.
- Viewing the page source (not the inspector, which shows the page after JavaScript) and searching for
ld+jsonfinds no block with"@type":"Product". - Search Console's Merchant listings or Product snippets reports show fewer valid items than you have products, or none.
- Two different Product blocks appear on the same page, one from the theme and one from an app, with different prices or names.
How to fix it in Shopify
- Test a few product URLs first. Run a simple product and one with variants through the structured data tester. Note whether the Product block is missing, broken, or present only after JavaScript.
- Work on a copy of the theme. In Online Store → Themes, duplicate the live theme and edit the copy (Actions → Edit code).
- Look for the existing block. Open the product section, usually
sections/main-product.liquid, and search forstructured_dataorld+json. If a block exists but fails to parse, the usual cause is a dynamic value printed without thejsonfilter. - Add Shopify's own output if there's none. Inside the product section, add
<script type="application/ld+json">{{ product | structured_data }}</script>. Shopify'sstructured_dataLiquid filter outputs a Product, or a ProductGroup when the product has variants. - Keep one source. If an app also outputs Product markup, turn one off. Prefer markup rendered in Liquid, on the server, over a script that injects it in the browser.
- Validate and publish. Re-test the copy's preview URL in the Rich Results Test, then publish the theme and re-test the live page.
Caveats and when it applies
- Valid structured data makes a page eligible for product rich results; it doesn't guarantee Google shows them.
- The markup has to describe what the page shows. Hand-written markup that hard-codes a price or availability creates a different problem: a mismatch with the live product.
- Headless storefronts (Hydrogen or another framework) don't use theme Liquid. The storefront has to render the JSON-LD into its server HTML itself.
- Theme updates can overwrite edits made in code. Keep a note of the change, or put the block in a snippet you re-add after updating.
Official documentation
- Google: Product structured data
- Google: Merchant listing structured data
- Google: Product variant structured data
- Shopify: Liquid filter: structured_data
- Shopify: Editing your theme with code
- schema.org: Product type
The audit checks behind this guide
No Product structured data on the page
Google can't verify price/availability from the page and AI agents see an unlabelled web page instead of a product.
Product structured data only appears after JavaScript runs
Google renders it eventually, but most AI crawlers (OAI-SearchBot, PerplexityBot, ClaudeBot) don't execute JavaScript — to them the product has no structured data at all.
Structured data block fails to parse
A broken JSON-LD block is silently ignored by every crawler — the product data in it doesn't exist for them.
Test it free: Paste a product URL and see the structured data in its HTML, whether it only appears after JavaScript, and what's missing.
Open the structured data tester →Updated 2026-10-26. catalogaudit isn't affiliated with Google or Shopify; the linked documentation is the authority.