How do I add Product schema to my Shopify store?
Most Shopify themes already output Product JSON-LD, but it's almost always incomplete — missing `offers.availability`, `priceCurrency`, or `aggregateRating`. To add or fix Product schema: audit what you have with Google's Rich Results Test, then either edit your theme's `product.liquid` template directly or use a schema app. Complete schema unlocks rich results in Google Search and improves how AI shopping tools read your catalog.

What Shopify Themes Actually Output (and What They Miss)
Shopify's default Dawn theme and most paid themes inject a Product JSON-LD block — but it's often bare-bones. You'll typically get name, description, and image, but the fields that actually trigger rich results — offers with price, priceCurrency, and availability, plus aggregateRating — are frequently absent or malformed. Google won't show a star rating snippet or a price in search results without those fields being correct.
The offers.availability field is the most commonly broken one. Themes often omit it entirely, or output a raw string like "In Stock" instead of the required schema.org URL format: "https://schema.org/InStock".
Step 1: Check What You Already Have
Before touching any code, audit your current output.
- Open a product page on your live store (e.g.,
yourstore.com/products/your-product-handle). - Go to Google's Rich Results Test and paste the URL.
- Click "Detected Items" — look for a
Productentry. - Expand it and check which fields are present vs. flagged with warnings or errors.
- Also open your browser's DevTools (View Source), search for
application/ld+json— you'll see the raw JSON Shopify is outputting.
Warnings in the Rich Results Test (yellow triangles) mean the field is missing but recommended. Errors (red) mean something is malformed and the rich result won't show.
Where Shopify Renders the JSON-LD
In most themes, the Product schema lives in one of two places:
sections/main-product.liquid(Dawn and newer themes) — look for ascript type="application/ld+json"block inside this file.layout/theme.liquid— older themes sometimes inject a global schema block here usingproductobject references.
To find it: in your Shopify Admin, go to Online Store → Themes → Edit Code, then search across files for application/ld+json. That string will lead you straight to it.
Required vs. Recommended Fields
Here's what schema.org/Product and Google's documentation actually require vs. recommend for a valid rich result:
| Field | Required / Recommended | Notes |
|---|---|---|
name | Required | Usually present in themes |
image | Required | Must be an absolute URL |
offers.price | Required | Numeric value, not a string with currency symbol |
offers.priceCurrency | Required | ISO 4217 code, e.g. "USD" |
offers.availability | Required | Must be a schema.org URL — https://schema.org/InStock |
brand.name | Recommended | Often missing; add your store or vendor name |
description | Recommended | Usually present |
aggregateRating | Recommended | Needed for star snippet; requires ratingValue + reviewCount |
sku | Recommended | Helps Google match to product listings |
How to Add or Complete the Schema
Option A: Edit the theme directly (best for developers or confident store owners)
Find the JSON-LD block in your theme and extend it. A complete, minimal example looks like this:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "{{ product.title | escape }}",
"image": "{{ product.featured_image | img_url: 'master' }}",
"description": "{{ product.description | strip_html | escape }}",
"sku": "{{ product.selected_or_first_available_variant.sku }}",
"brand": { "@type": "Brand", "name": "{{ shop.name | escape }}" },
"offers": {
"@type": "Offer",
"price": "{{ product.price | money_without_currency }}",
"priceCurrency": "{{ cart.currency.iso_code }}",
"availability": "{% if product.available %}https://schema.org/InStock{% else %}https://schema.org/OutOfStock{% endif %}",
"url": "{{ shop.url }}{{ product.url }}"
}
}The aggregateRating block requires actual review data — wire it to your review app's Liquid objects (e.g., Judge.me or Okendo expose metafields you can reference).
Option B: Use a schema app
Apps like Shopify's SEO tools or third-party schema apps can inject complete JSON-LD without touching code. The tradeoff: some apps output schema that conflicts with your theme's existing block, creating duplicate Product entries — which Google will ignore or flag. Always re-run the Rich Results Test after installing any schema app.
Step 2: Verify After Making Changes
- Save your theme changes and visit a live product URL.
- Re-run the Rich Results Test — confirm zero errors and minimal warnings.
- Check Google Search Console under Enhancements → Products for index-wide coverage after a few days.
- Validate the raw JSON at validator.schema.org for structural correctness beyond what Google's tool checks.
Running a free StoreCited scan is the fastest way to surface which of your product pages have incomplete or broken schema at scale — rather than checking URLs one by one in the Rich Results Test.
Common Mistakes to Avoid
- Duplicate JSON-LD blocks: If your theme already has a
Productschema and you add an app, you'll have two. Google picks one arbitrarily — usually the wrong one. - Price with currency symbol:
"$29.99"will fail. Usemoney_without_currencyin Liquid and setpriceCurrencyseparately. - Relative image URLs: Schema validators require absolute URLs. Use
img_url: 'master'to get the full CDN path. - Hardcoded availability: Don't write
"InStock"as a static string. Use Liquid logic so it updates when variants go out of stock.
Get the answer for your specific store