Why a schema mismatch matters
Most Shopify product pages include a block of JSON-LD (<script type="application/ld+json">) describing the product with schema.org vocabulary: Product (or ProductGroup for products with variants) and one or more Offer objects carrying price, priceCurrency and availability.
Machines read this block because it is easier than parsing your design. Google Merchant Center, for example, documents that its automatic item updates read the schema.org price, currency and availability on your landing pages to correct temporary feed mismatches, and that it may stop trusting a site's annotations if they are not accurate. AI shopping agents that crawl or fetch your pages can rely on the same data. If the JSON-LD says 39.00 and the page says 29.00, someone downstream gets the wrong number.
Google's merchant listing documentation lists price (greater than zero) and priceCurrency as required on the Offer, with availability recommended.
What a consistent Offer looks like
For a product shown at 29.00 Canadian dollars and in stock, the Offer in the JSON-LD should carry the same facts, nothing more clever:
"@type": "Offer""price": "29.00"(the price the shopper pays now, not the compare-at price)"priceCurrency": "CAD"(the currency shown on the page for that market)"availability": "https://schema.org/InStock"(orOutOfStockwhen the page says sold out)"url"pointing to the product or variant URL where it can be bought
For a product with variants, each variant should have its own Offer with its own price, availability and SKU. If one variant is sold out and another is not, the schema should say so.
How to check a product page by hand
- Pick test pages. Choose a product on sale, a product with several variants at different prices, and a product that is out of stock. Mismatches hide in these cases, not in the simple ones.
- View the source. Open the page, press Ctrl+U (Cmd+Option+U on Mac) and search for
ld+json. Count the blocks. More than oneProductblock is a warning sign. - Read the Offer. In each block, note
price,priceCurrency,availabilityand the variantskuorurl. - Compare with the page. Is the visible price the same, including sale price? Same currency? Does the page say sold out while the schema says
InStock? - Run Google's Rich Results Test at search.google.com/test/rich-results. It shows the structured data Google extracts and flags missing required fields. It does not tell you whether the value matches the visible price; that comparison is yours to make.
- Switch variant and market. Select another variant and, if you sell in several countries, view the page as a shopper from another market. Check again.
Common causes on Shopify
Hard-coded or old theme blocks
Some themes, or snippets added by a developer years ago, print a fixed price, a fixed currency or InStock regardless of the variant. Others were built before the theme started using Shopify's structured_data Liquid filter. When the theme is updated or customized, an old snippet can stay behind and output a second, stale block.
SEO, review and feed apps adding their own schema
Schema and review apps often inject their own Product markup. If the theme also outputs one, you end up with two Product blocks that may disagree, for example one with the sale price and one with the compare-at price. Removing an app does not always remove what it added to theme files.
Variants
The default view usually shows the first available variant. A schema snippet that always reads the first variant will be wrong when the shopper lands on a variant URL with a different price or stock status.
Multiple currencies and Shopify Markets
With Shopify Markets, the visible price can be in the shopper's local currency. If the JSON-LD hard-codes the store's default currency, or uses shop.currency, the number and the currency code can stop matching outside your home market.
Sales, discounts and caching
Prices changed by an app or a script after the page loads can differ from the price in the server-rendered JSON-LD. A sale started by a pricing app may show on screen but not in the schema, or the reverse.
Mismatch checklist
| What to compare | Typical symptom | Where to fix |
|---|---|---|
| Price | Schema shows compare-at or old price | Theme product template or schema app settings |
| Currency | CAD on page, USD in schema | Use the market's currency, not a fixed code |
| Availability | Sold out on page, InStock in schema | Snippet should read the selected variant |
| Number of Product blocks | Two blocks with different values | Disable one source: theme or app |
| Variant | Variant URL shows first variant's price | Output one Offer per variant |
| Missing block | No ld+json at all | Theme lacks structured_data; ask your developer or theme support |
How to fix it without breaking anything
- Keep one source of truth. Decide whether the theme or an app outputs Product schema, and turn the other off.
- Prefer Shopify's own filter. Current Shopify themes use
{{ product | structured_data }}, which reads live product data. If you extend it with your own snippet, read values from the selected variant, not fixed text. - Test on a duplicate theme before publishing, then repeat the hand check above.
- Recheck after changes. Installing a reviews app, switching themes or adding a market can reintroduce a mismatch months after you fixed it.
Checking every product automatically
The hand check works for a few pages. It does not scale to a catalog, and it only tells you about today. AI Sales Assurance runs this comparison across your products: it flags missing JSON-LD and JSON-LD that disagrees with the page, along with price, currency, availability and variant mismatches, and explains which theme block or app is the likely source. It is read-only and never edits your store. Run a free check, or see how continuous monitoring catches mismatches when they come back.
Check what AI shopping agents see in your store
Free, read-only check: prices, stock, variants, structured data and links compared with your real product pages. No credit card.
Run my free checkFrequently asked questions
How do I check my product schema on Shopify?
View the page source and search for ld+json, then run the URL through Google's Rich Results Test. Compare the price, currency and availability in the Offer with what the page shows.
Why does my structured data show a different price than my page?
Usually a hard-coded theme snippet, a second Product block from an SEO or reviews app, a snippet that reads the first variant only, or a currency fixed to your default market.
Does Google's Rich Results Test detect price mismatches?
No. It shows the structured data Google extracts and flags errors in required fields, but you must compare the values with the visible page yourself.
Can I have two Product schema blocks on one page?
It is best avoided. Two blocks with different values leave crawlers and agents to guess which is right. Keep one source, either the theme or one app.