When an AI shopping assistant or Google's merchant crawler looks at a product page, it rarely "sees" the page. It reads the structured data: the Product JSON-LD block with price, availability, identifiers, shipping and returns. Whatever is not in that block may as well not exist for a machine.
On 4 November 2026 I checked one product page each from 21 well-known Shopify brands. 14 came back with a readable page; the rest are covered at the end.
Disclosure: I built the checker used here, the Product Schema Checker on Apify. How to run it on your own pages is at the end.
/products.json feed, so the sample is not cherry-picked.Product was scored against what Google's merchant listings and AI shopping agents use: name, image, price, currency, availability, brand, identifiers (GTIN/SKU/MPN), rating, reviews, item condition, shipping details and return policy.
All 14 pages had a Product in JSON-LD with:
That is Shopify's theme layer doing its job. Any store on a modern theme gets these for free.
The median score was 75 of 100. The points were lost on the same fields again and again:
| Field | Pages that have it |
|---|---|
shippingDetails (shipping cost and time) |
2 of 14 |
hasMerchantReturnPolicy |
3 of 14 |
aggregateRating (star rating) |
4 of 14 |
gtin (barcode) |
4 of 14 |
review (individual reviews) |
0 of 14 |
itemCondition |
5 of 14 |
Only Outdoor Voices (94) and Taylor Stitch (92) declared both shipping and returns in their markup. Everyone else leaves an assistant to guess the two questions shoppers ask most: "what does delivery cost?" and "can I send it back?"
Three observations from the details:
1. Ratings may be on the page, but not in the data. In the plain HTML, only 4 of 14 expose aggregateRating, and none has individual reviews. Most review widgets load with JavaScript after the page renders, so if a store shows stars that way, a crawler that does not run scripts never sees them. Most review apps can write a JSON-LD rating into the theme. It is usually one setting.
2. GTINs are rare and not always real. Only 4 pages had a gtin field. One of them contained 15U2UGGFXG60, which is not a valid GTIN at all (GTINs are 8, 12, 13 or 14 digits with a check digit). It looks like an internal SKU in the wrong field. Google matches products across shops by GTIN, so a wrong value can hurt more than a missing one.
3. "Out of stock" is often the theme's default. 4 of the 14 pages declared OutOfStock, although the product was listed in the store's live feed. One possible cause on Shopify: the markup describes only one variant (for example a sold-out size). An agent then reads the whole product as unavailable.
So a third of the sample turned away a polite, single request from a data center. That is a defensible security choice. But it is worth knowing that some AI assistants fetch pages from similar infrastructure, and a shop that rate-limits them by default may be invisible to them.
hasMerchantReturnPolicy and shippingDetails to the product JSON-LD. Google also lets you set them once at the organization level. Both are static for most shops: write them once and you are done.aggregateRating is in the HTML and not only in the widget.ProductGroup or multiple Offer s), not just the first.
curl -X POST "https://api.apify.com/v2/acts/fast_data_asap~product-schema-checker/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"startUrls": ["https://your-store.com/products/your-product"]}'
You get one flat row per URL: all schema types found, the product fields, missingRequired, missingRecommended, a score and grade, and concrete fix hints. It costs $0.002 per product page found; pages without product markup, blocked pages and errors are free. The 21 pages here took a few seconds.
For barcodes, the EAN/GTIN Lookup validates check digits and looks up open product data for $0.0002 per code.
Data: one product page each from 21 Shopify stores, plain HTTP, 4 November 2026. A different product or a crawl from another network can give different results.