A JSON-LD block is useful only when it describes the product a shopper can actually buy. Valid JSON with the wrong stock state, market, SKU, or review count is still bad evidence.
This reference uses public observations captured on July 27, 2026. The stores are examples, not SkuWatch AI Visibility customers, and no endorsement is implied.
Start with the rendered page
Save the same response a public retrieval client receives:
url='https://example.com/products/example-product'
curl -sSL -D response-headers.txt "$url" -o product.html
rg -n 'rel="canonical"|application/ld\+json|"@type"|"availability"|"price"' product.html
Do not inspect only the Shopify theme editor. Review apps, SEO apps, and client-side scripts can add a second product entity after the theme renders.
Product-level fields
| Field | What it should identify | Common Shopify failure | Acceptance test |
|---|---|---|---|
@id |
Stable identity for this product or product group | Two apps create unrelated IDs for one item | Every connected entity refers to one deliberate ID graph |
name |
Public product name | Internal Default Title leaks into the name |
Matches the visible title and selected variant context |
url |
Canonical product or variant URL | Collection path or wrong market URL | Resolves to the intended product without a redirect chain |
brand |
Manufacturer or merchant brand | Skill level or product type placed in brand | Matches visible branding and catalog ownership |
sku |
Stable sellable item identifier | Parent SKU reused across different sizes | Each inventory-distinct variant is recoverable |
category |
Product taxonomy | Promotional collections copied into category | Describes what the product is, not the campaign it belongs to |
description |
Factual product summary | Generic marketing copy without decisive facts | Includes the same essential facts visible on page |
image |
Representative product media | Stale or variant-incompatible image | Corresponds to the selected product or variant |
Observed failure: HexClad Default Title
The public HexClad UK six-piece pot set returned one Product entity named:
HexClad Hybrid Pot Set 6 PC — Default Title
The visible page presents a clean bundle name, £399 price, and 2 L, 3 L, and 7.5 L included pots. Default Title is an internal one-variant Shopify label; it adds no customer meaning and should not appear in public entity identity.
Shopify repair location:
- inspect the theme or app block emitting Product JSON-LD
- use the product title when the only variant title is
Default Title - preview a simple product and a multi-variant product
- confirm the public JSON-LD, not only Liquid source
ProductGroup and variants
Use a parent product group when variants differ by a meaningful sellable property such as size, colour, capacity, or license. The parent describes shared identity; each variant carries its own SKU and offer.
Observed Rhode example:
| Structured name | Price | Availability | Observed SKU |
|---|---|---|---|
| glazing milk — big (4.2 oz) | $32 USD | InStock | RHS00025-SC1 |
| glazing milk — little (1.7 oz) | $20 USD | InStock | RHS00025-SC1 |
The two size offers are clear, but the same observed SKU weakens variant identity. If the sellable variants have separate inventory records, expose separate stable identifiers.
Offer-level fields
| Field | Required interpretation | Frequent error |
|---|---|---|
price |
Current amount payable for this offer | Old price or compare-at price used as current price |
priceCurrency |
Currency of the rendered market | USD schema on a CAD or GBP page |
availability |
Current selected offer state | InStock while the buy button says sold out |
url |
Offer or selected variant destination | URL opens a different variant |
sku |
Identifier for the offered item | Parent SKU substituted for variant SKU |
priceValidUntil |
Real expiry when known | Invented or permanently extended date |
seller |
Entity making the offer | Marketplace or brand relationship misrepresented |
Observed failure: The Woobles availability
The Pierre the Penguin page visibly showed Sold out, while both observed Product offers reported InStock. A recommendation system can repeat the machine-readable value and send a shopper to an unavailable item.
The correct repair is not to hard-code OutOfStock. It is to connect Offer.availability to the same Shopify variant availability state used by the buy box.
Reviews and ratings
aggregateRating should answer four questions:
- Which product or product group do the reviews cover?
- Is the rating visible to the shopper?
- Is the count current?
- Did more than one app emit a competing aggregate?
On the observed Woobles page, visible review evidence showed 1,874 reviews, while one Product entity exposed a zero rating and zero count. On Rhode, both size entities exposed the same 4.7 rating and 6,326-review count, suggesting a shared formula-level review population. Both cases require explicit scope.
Never create aggregate markup from testimonials that are not presented as product reviews.
Market and canonical consistency
The Mattel Creations collector-doll request resolved to a Canadian path and exposed a CAD 455 out-of-stock offer, while the canonical pointed to a non-localized product URL. That may be an intentional consolidation strategy, but the product entity still needs enough market context to prevent a CAD offer being interpreted as a universal price.
Record requested URL, final URL, canonical, locale, currency, and availability together.
Duplicate Product audit
Use this browser-console inventory:
[...document.querySelectorAll('script[type="application/ld+json"]')]
.map((node, index) => {
try {
return { index, data: JSON.parse(node.textContent) };
} catch (error) {
return { index, error: error.message };
}
});
For every Product or ProductGroup, write down its theme or app owner. Multiple entities are acceptable only when they form a deliberate graph and agree on commercial facts.
Minimum acceptance checklist
- canonical,
@id, andurldescribe the intended product - variant name, SKU, price, currency, and stock agree with the selected UI state
- no
Default Title, promotional collection, or placeholder brand leaks into identity - visible reviews and structured ratings have the same scope
- bundle attributes remain attached to included items
- market redirects do not separate an offer from its currency and region
- removing a duplicate block does not remove a visible review or product feature
For implementation steps, use the Product JSON-LD inspection guide.