ShipworkSite inspection
Checks
Every error, explainedGuides →
Pricing Learn Guides

Would Google show a rich result for this product page?

Structured data can be valid and still be useless for shopping. This check first decides whether the page is a product page at all, then reads the fields a rich result and a free listing need, from the shopping angle rather than the schema angle.

Reads one page, decides whether it is a product page, then reports the shopping fields Google needs. Nothing is stored.

What this check inspects

Shipwork fetches the page and decides what it is. It treats the page as a product page when it finds Product or ProductGroup JSON-LD, microdata or RDFa product markup, an og:type of product, or a price together with an add-to-cart control. Only then does it check the shopping fields: name, an image that is an absolute URL, an offers object, price, priceCurrency, availability, a product identifier such as gtin, mpn, sku or isbn, brand, aggregateRating against the individual reviews, and shippingDetails and hasMerchantReturnPolicy for a product that ships. Microdata and RDFa are read too, and reported as a format opportunity rather than a failure.

What a failure means

A page that reads as a product but carries no Product markup is a warning, because Google has to infer the fields. Once markup is present, a missing name, a missing image, no offers, or offers with no price are errors, because each one blocks a rich result or a shopping listing. Missing priceCurrency, missing availability, an unrecognised availability value, no identifier, no brand, an aggregateRating that disagrees with the reviews on the page, and missing shipping and return fields are warnings. A page that is not a product page returns one informational finding and nothing else, so a blog post is never told it needs a price.

How to fix it

  1. Add Product or ProductGroup JSON-LD with a name, at least one absolute image URL, and an offers object carrying price, priceCurrency and availability.
  2. Put the offers on each variant when you use ProductGroup, so a variant page is not reported as having no offer.
  3. Add a gtin, mpn, sku or isbn so Google can match the page to its catalogue entry.
  4. Set the brand field, and make aggregateRating.reviewCount match the number of reviews on the page.
  5. Set shipping and returns in Merchant Center where possible, and add shippingDetails and hasMerchantReturnPolicy to the offer for the free listings experience.

A typical failure, worked through

The setupA store hand-builds a product template that emits Product JSON-LD with a name and an image but an offers object that carries only a URL. The same theme change also drops the availability field the old template emitted.

What the check reportsThe check confirms the page is a product page, then reports that the offers are missing a price and that availability is missing, while the page itself renders a price and a button.

The pointThe page looks complete to a shopper and incomplete to Google. The check reads the shopping fields, not the rendered page, which is why the two disagree.

Questions

Is this the same as the structured data check?
No. The structured data check validates JSON-LD format on any page. This check first decides whether the page is a product page, then reports the shopping fields that decide rich results and free listings, including microdata and RDFa which the other check does not read.
Why did it say nothing about my blog post?
Because the page did not read as a product page, so there were no shopping fields to check. A checker that warns every article about a missing price is one people stop reading.
Where should hasMerchantReturnPolicy go?
On the Offer, not the Product. Placed on the Product it is ignored for merchant listings.

Related checks and guides