Aizii Learn · AI Search
← Back to Learn

How to add product schema on Shopify

On Shopify you usually do not add product schema from scratch. Modern Shopify themes, including Dawn, already emit a Product JSON-LD block on every product page, so the job is to check what your theme outputs, fill in the missing fields, and remove the duplicate blocks your apps add. The one constraint shaping everything on Shopify is that theme code is yours to edit but theme upgrades and app installs overwrite or duplicate your work, so the markup has to live somewhere that survives both.

Why Shopify is different

Three things are specific to the platform. First, the theme is the markup source. Shopify renders product pages from Liquid templates on its servers, and the JSON-LD block lives in those templates, not in any settings panel. Second, there is no server access and no plugin layer like WordPress. Everything goes through theme files, apps, or product descriptions. Third, apps are the usual duplicate source. SEO and review apps inject their own Product blocks, and a page with two conflicting blocks (one from the theme, one from the app) is the single most common Shopify schema failure.

Steps

1. Check what already exists. Open a live product page, view the page source (not the rendered page), and search for application/ld+json. Count the Product blocks and figure out which one the theme emits and which ones apps emit. Do this before touching anything.

2. Fix the theme block instead of adding a second one. If the theme already outputs a Product block, extend it in the theme code rather than pasting a new one next to it. In your Shopify admin, go to Online Store, then Themes, open the menu on your live theme, and choose Edit code. Find the product template (in most current themes it is a section file like main-product.liquid; the exact file varies by theme, so search the theme for the existing application/ld+json script and work where you find it).

A minimal addition inside the product template looks like this, pulling values from Liquid variables so the markup always matches the page:

{% if template.name == 'product' %}
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": {{ product.title | json }},
  "brand": { "@type": "Brand", "name": {{ product.vendor | json }} },
  "offers": {
    "@type": "Offer",
    "price": "{{ product.selected_or_first_available_variant.price | money_without_currency }}",
    "priceCurrency": "{{ cart.currency.iso_code }}",
    "availability": "https://schema.org/{% if product.available %}InStock{% else %}OutOfStock{% endif %}"
  }
}
</script>
{% endif %}

Use the json filter on text values so quotes in product titles cannot break the JSON. Keep brand, availability, and currency dynamic. A hardcoded price in a Liquid template is stale markup the moment you run a sale.

3. Only add a full block if the theme has none. Older or heavily customized themes sometimes have the markup stripped out. In that case add one complete Product block in the product template using the variables above, then compare it field by field against the pillar reference.

4. Eliminate the duplicates. If a review app or SEO app emits its own Product block, you now have two competing sets of facts. Pick one source of truth. Either disable the app's schema output (most apps have a toggle) or remove the theme block and let the app own it. Never leave both.

5. Validate like a variant buyer would. Test a URL such as https://[yourdomain.com]/products/your-product, replacing yourdomain.com with your actual domain, in Google's Rich Results Test and the Schema Markup Validator. Include at least one variant URL and one out-of-stock product. The out-of-stock check matters because availability is the field that goes stale first.

6. Plan for theme changes. Manual edits do not carry over when you switch themes. Note what you changed and where, so the markup survives the next redesign.

The fundamentals

A hypothetical example

Say you run a coffee gear store on Shopify with 60 products and a reviews app. You view a product page source and find two application/ld+json blocks: the theme emits price and availability but no brand, and the reviews app emits a second Product block with the rating but a different price format. The fix is not a third block. You disable the app's product schema output, keep the theme block, and add brand and the aggregate rating fields to the theme template with Liquid variables. One block, generated from the same data that renders the page.

What this guide does not cover

This covers getting valid product markup onto your Shopify product pages. It does not cover keeping that markup accurate as prices and inventory change (that is monitoring work), getting AI crawlers past your edge and CDN setup, or letting an agent complete the checkout, which is the transaction layer and a separate job.

Frequently Asked Questions

Where is product schema typically added in a Shopify theme?
In your theme files, inspect sections/main-product.liquid or snippets/product-media.liquid where JSON-LD script tags are defined.
How do I avoid conflicting schema outputs from Shopify apps?
Review your page source for multiple application/ld+json scripts. Disable structured data in third-party review apps if your theme already outputs valid product schema.
Does Shopify include variant pricing in product schema?
Most modern themes include variant offers with individual price and availability values within an offers array.

Check your own brand now

Run the free scan. It takes seconds, no signup, and shows whether AI crawlers can read your product pages today: aizii.ai/aeo-scan

Run the free scan