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
- Add Product or ProductGroup JSON-LD with a name, at least one absolute image URL, and an offers object carrying price, priceCurrency and availability.
- Put the offers on each variant when you use ProductGroup, so a variant page is not reported as having no offer.
- Add a gtin, mpn, sku or isbn so Google can match the page to its catalogue entry.
- Set the brand field, and make aggregateRating.reviewCount match the number of reviews on the page.
- 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.