Fix Missing Product Schema on Shopify
Critical PriorityMissing Product schema means your products cannot appear with rich results (price, availability, star ratings) in Google Search. Add a JSON-LD script block to your product template with the full Product type including name, image, description, brand, offers (with price, priceCurrency, availability, url), and if applicable, AggregateRating. Test with Google's Rich Results Test after adding.
The Problem
Product pages without JSON-LD structured data cannot qualify for Google's rich results - the enhanced search listings that show price, availability, star ratings, and review counts directly in search results. Rich results significantly increase click-through rate and product visibility.
Impact: Products with valid Product schema and rich results receive 20-30% higher CTR than plain blue-link results. Rich results also improve brand trust, as showing live price and stock directly in search results reduces bounce from searchers expecting something different.
How to Fix It (Step-by-Step)
Check whether product schema already exists
Right-click a product page → View Page Source → search for "application/ld+json" and "@type": "Product". If found, check the fields rather than adding a duplicate. Many Shopify themes include basic schema that is incomplete or uses deprecated img_url filter.
Open the correct template file in your theme
In Online Store → Themes → Edit code, open either sections/product-template.liquid, sections/main-product.liquid, or templates/product.liquid depending on your theme. For Online Store 2.0 themes (Dawn, Sense, Crave), the schema section is usually in sections/main-product.liquid.
Add the full Product JSON-LD schema block
Paste the complete schema before the closing </section> tag or at the bottom of the product section file. Use the full schema shown in the code example below - do not use a stripped-down version.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "{{ product.title | escape }}",
"image": [
{%- for image in product.images limit: 5 -%}
"{{ image | image_url: width: 1200 }}"{% unless forloop.last %},{% endunless %}
{%- endfor -%}
],
"description": "{{ product.description | strip_html | strip_newlines | truncate: 500 | escape }}",
"sku": "{{ product.selected_or_first_available_variant.sku | escape }}",
"brand": {
"@type": "Brand",
"name": "{{ product.vendor | escape }}"
},
"offers": {
"@type": "Offer",
"url": "{{ shop.url }}{{ product.url }}",
"priceCurrency": "{{ cart.currency.iso_code }}",
"price": "{{ product.selected_or_first_available_variant.price | divided_by: 100.0 }}",
"priceValidUntil": "{{ 'now' | date: '%Y' | plus: 1 }}-12-31",
"availability": "{% if product.available %}https://schema.org/InStock{% else %}https://schema.org/OutOfStock{% endif %}",
"itemCondition": "https://schema.org/NewCondition",
"seller": {
"@type": "Organization",
"name": "{{ shop.name | escape }}"
}
}
}
</script>Verify price outputs correctly
Shopify stores prices in cents (integer). {{ product.price }} returns 2999 for £29.99. Always use | divided_by: 100.0 to get the decimal price, or use | money_without_currency for a formatted string. Both are accepted by Google, but divided_by: 100.0 is safer for international schemas.
Add AggregateRating if you have product reviews
If you use a reviews app (Judge.me, Okendo, Yotpo), add the AggregateRating property to enable star ratings in search results. You'll need the app's metafield or liquid object - check the app's documentation for the correct variable name.
Test with Google's Rich Results Test
Go to search.google.com/test/rich-results and enter your product URL. The test will show whether Google can parse your schema and which rich result features are eligible. Address any warnings shown - particularly missing recommended fields.
Submit for re-indexing in Google Search Console
Use the URL Inspection tool in Search Console → paste your product URL → Request Indexing. This accelerates when Google processes the new schema.
Monitor rich result status
After 2-4 weeks, check Search Console → Enhancements → Products. This report shows the count of pages with valid, warnings, or errors in product schema. Fix any errors shown before they affect existing rich results.
Common Mistakes to Avoid
Using img_url instead of image_url in schema
The img_url Liquid filter is deprecated since Shopify's 2022 API update. Use image_url: width: 1200 instead. Some themes still use img_url in their schema, which outputs a URL that may stop working. The image_url filter is the current standard and produces CDN-optimised URLs.
Outputting price without dividing by 100
Shopify's {{ product.price }} returns the price in cents (pence/øre/etc.). Putting "2999" in the schema price field when the actual price is £29.99 will cause Google's structured data validator to flag the price as suspicious, and your rich results may not display.
Adding schema only to the homepage or a single template
Product schema must be on every product page individually - it cannot be inherited. If your theme has multiple product templates (e.g., template/product.json and template/product.preorder.json), each template file needs its own schema section.
Complete Code Example
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "{{ product.title | escape }}",
"image": [
{%- for image in product.images limit: 5 -%}
"{{ image | image_url: width: 1200 }}"{% unless forloop.last %},{% endunless %}
{%- endfor -%}
],
"description": "{{ product.description | strip_html | strip_newlines | truncate: 500 | escape }}",
"sku": "{{ product.selected_or_first_available_variant.sku | escape }}",
"brand": {
"@type": "Brand",
"name": "{{ product.vendor | escape }}"
},
"offers": {
"@type": "Offer",
"url": "{{ shop.url }}{{ product.url }}",
"priceCurrency": "{{ cart.currency.iso_code }}",
"price": "{{ product.selected_or_first_available_variant.price | divided_by: 100.0 }}",
"priceValidUntil": "{{ 'now' | date: '%Y' | plus: 1 }}-12-31",
"availability": "{% if product.available %}https://schema.org/InStock{% else %}https://schema.org/OutOfStock{% endif %}",
"itemCondition": "https://schema.org/NewCondition",
"seller": {
"@type": "Organization",
"name": "{{ shop.name | escape }}"
}
}
}
</script>Frequently Asked Questions
Q: Does my Shopify theme already include product schema?
Many Shopify themes (especially Dawn and other OS 2.0 themes) include basic Product schema, but it is often incomplete. Common missing fields include sku, priceValidUntil, itemCondition, and seller. Run your product URL through Google's Rich Results Test to see exactly what schema is present and what fields are flagged as missing or invalid.
Q: Do I need a Shopify app to add product schema?
No. Product schema is added directly to your theme's Liquid template files - no app is required. However, if you use a reviews app, you will need that app's metafield variables to add AggregateRating data. Some SEO apps like TinyIMG or Yoast for Shopify can also inject schema, but hand-coded schema in your theme is more reliable and avoids render-blocking scripts.
Q: How long does it take for product schema to appear as rich results in Google?
After adding correct schema and requesting re-indexing in Search Console, rich results typically appear within 1-4 weeks depending on how frequently Google crawls your store. Stores with more backlinks and traffic are crawled more frequently. You can track eligible pages in Search Console under Enhancements → Products.
Not Sure If You Have This Issue?
Run a free scan to detect this and other SEO problems on your Shopify store instantly.
Free SEO ScanOther Common Shopify SEO Issues
Go Deeper
Deep Dive: Missing Product Schema
Detailed technical documentation - seoscan.dev/shopify/missing-product-schema
Related Scan Topic
seoscan.dev/shopify-seo-scan/schema-markup
All Shopify SEO Issues
Browse the full Shopify SEO issue library