ShipworkSite inspection
Checks

Crawlability

PaginationAre paginated pages set up right?Internal searchIs site search eating crawl budget?URL parametersAre parameters creating duplicates?Log analyserWhat does Googlebot actually crawl?Robots builderNeed a robots.txt file?Soft 404sAre pages “not found” but returning 200?JavaScriptCan crawlers see it without running JS?FreshnessIs my site quietly going stale?Robots.txtDoes robots.txt say what I think?

Indexing

Sitemap lastmodAre my sitemap dates valid?SitemapIs my sitemap actually fetchable?IndexingIs Google allowed to index my pages?CanonicalsIs Google indexing the wrong URL?Index signalsDo sitemap and index signals agree?Sitemap generatorNeed a sitemap.xml for my site?Bulk URL statusWhere does each of these URLs really land?Redirect builderNeed the redirect rules?RedirectsAre my URLs answering directly, over HTTPS?

On-page

Keyword ideasWhat are people searching for?SERP previewHow does my page look in Google?Content qualityAre your pages too thin or too alike?Image weightAre images slowing the page?CannibalizationAre pages competing with each other?On-page checkDoes the page use its target phrase?ImagesAre my images accessible and loading?Meta tag builderWhat should my title and share tags say?DuplicatesDo my pages compete for one query?

Links

Orphan pagesWhich pages can no link reach?Link graphHow deep do your pages sit?Anchor textDo links say what they point at?Outbound linksAre external links still alive?Broken linksAre internal links sending visitors nowhere?

Structured data

Rich resultsIs my markup eligible for a rich result?Structured dataIs my product schema valid?Schema coverageDo my key pages carry structured data?Social previewHow does my page look when shared?Schema vs pageDoes markup match the page price?Schema builderNeed valid JSON-LD?

International

Hreflang sitemapDo page and sitemap hreflang agree?HreflangDo my language versions link back?Hreflang builderNeed the hreflang tags?Page DoctorWhy is this page not doing well?Redirect planMy site has dead links — what redirects do I write?Sitemap diffIs anything missing from my sitemap?Robots simulatorWhat does my robots.txt actually block?Can Googlebot?Can Googlebot fetch this URL?
Every error, explainedGuides
Pricing Learn Error guides Run free audit

+1 free check

Welcome to Shipwork

Sign in free and your next check this month is on us.

Continue with GoogleContinue with email

We email you a 6-digit code. No password.

No card needed. Reports and watches follow you to any device.

Product schema on Shopify: what the theme gives you and what it hides

Every modern Shopify theme ships Product markup. And a surprising number of stores still show warnings for it. The gap is not that the theme emits nothing; it is that what it emits is incomplete, and what breaks it is invisible in the browser. This guide covers the full picture: the auto-emitted fields, the five missing ones, variants, and validation that actually means something.

What the theme emits

Open view-source on a Dawn-based product page and you will find a Product JSON-LD block with the basics: name, image, description, SKU, brand from the vendor field, and an offers object carrying price, currency, availability and URL. That is genuinely useful: it is enough for a basic product snippet. What the theme does not reliably emit is everything Google added to the merchant-listing requirements afterwards: GTIN from the barcode field, aggregateRating and review data, hasMerchantReturnPolicy, shippingDetails, and proper variant structure. So the theme is both done and unfinished, depending on which surface you care about.

THEME EMITSname · image · pricecurrency · availabilitybrand · sku · urlTHEME OMITSgtin · shippingDetailshasMerchantReturnPolicyvariants · reviews
The theme covers snippets; merchant listings need the right column too. Layer the missing fields on top instead of duplicating the block.

Snippets versus merchant listings

Google uses product markup on two distinct surfaces. Product snippets enrich ordinary search results with price, availability and ratings: the theme output is usually enough here. Merchant listings power Shopping surfaces and carousels, and they demand agreement between the page markup and the Merchant Center feed, plus the return and shipping fields. A store can have perfect snippets and still be thin on merchant listings. Know which surface you are fixing before touching code.

The five missing-field warnings, explained

  • shippingDetails. The delivery cost and time Google shows beside the price. Easiest fix is not in the theme at all: set shipping in Merchant Center once and Google uses it everywhere.
  • hasMerchantReturnPolicy. Same story: set the return policy in Merchant Center and the warning is covered account-wide. Page-level markup only matters for per-product exceptions.
  • aggregateRating. Only valid with genuine independent reviews on the page. Self-serving review markup does not earn stars and can draw penalties. Never fabricate it.
  • review. For editorial or critic reviews, not customer ratings on your own products. Most stores should simply not have it.
  • priceValidUntil. Worth setting on genuine sale prices; Shopify has no native field for it, so it needs custom markup or an app.

For implementation detail, see the shipping and returns markup guide and a worked Product JSON-LD example. The pattern: set account-level truth in Merchant Center first, reserve page surgery for genuine per-product exceptions, and never invent values. Markup that misstates policy or ratings is a data-quality violation, not an optimization.

Variants and ProductGroup

A product sold in five sizes is not one product to Google, or rather, it should not be. The correct structure is a ProductGroup with each variant nested under hasVariant carrying its own offer, price and availability. Many themes emit a single flat Product for the default variant instead, which under-represents the catalogue and confuses naive validators into reporting markup as missing when it is merely nested. Any checker worth trusting parses ProductGroup and hasVariant; anything else cries wolf on modern themes.

How to validate like a crawler

  1. Use view-source, not the inspector. The inspector shows the page after scripts run; crawlers read raw HTML. Markup injected client-side is invisible to them.
  2. Search the source for application/ld+json and confirm a Product block exists server-side.
  3. Run the URL through the Rich Results Test and clear errors first, warnings second.
  4. Confirm the feed agrees with the page on price, currency and availability. Markup can be valid and still mismatch.
  5. Re-validate after every theme update. Schema snippets are among the first casualties of template changes.
Find out if this is happening to you

Shipwork fetches the raw HTML of a real product page, parses every JSON-LD block including nested ProductGroup and hasVariant, and names each missing field. Free, no account, no signup. Paste your store address.

Check my markup

Questions

Why does Search Console warn about shippingDetails if I set shipping in Merchant Center?
Because Search Console reads the page, not your Merchant Center account. With account-level shipping set, the warning is non-critical: but per-product exceptions still need page markup.
My theme emits Product schema: why do validators say markup is missing?
Two usual causes: the markup is injected by JavaScript after load so raw HTML has none, or the theme emits ProductGroup with variants nested and the validator only looks for flat Product.
Should I add aggregateRating to get stars?
Only with genuine independent reviews on the page. Fabricated or self-serving ratings violate the guidelines and can suppress the listing.
Where does the markup go in the theme?
Server-rendered product templates, so it ships in the raw HTML. Never rely on client-side injection for structured data.

Keep reading