Structured Data — Products
Product-level structured data is the single most impactful GEO investment for any ecommerce site. Without it, AI systems must guess relationships between variants, reviews, pricing, and brand — and they frequently get it wrong.
This page covers every schema type needed for a complete, AI-readable product knowledge graph.
Why Product Schema is Critical
Without structured data, AI systems:
- Treat each product variant as a separate, unrelated product
- Fragment review authority across isolated entities
- Cannot build accurate product family graphs
- Lose confidence in entity matching and citation
With strong product schema, AI systems can:
- Understand entire product families as connected entities
- Consolidate reviews and ratings to the canonical product group
- Follow explicit variant relationships
- Trust pricing, availability, and specification data
1. ProductGroup Schema
ProductGroup is the parent entity for any product that has multiple variants (sizes, colors, materials, configurations). This is the most critical ecommerce schema type for GEO.
Without ProductGroup: each color of a shoe appears as a completely separate, disconnected product.
With ProductGroup: the AI understands "New Balance 990v6" as one product family with 12 color variants.
Correct Structure
{
"@context": "https://schema.org",
"@type": "ProductGroup",
"@id": "https://www.example.com/product/5-inch-senko/#productgroup",
"name": "5\" Senko Worm 10pk",
"description": "Soft plastic stick bait for bass fishing. Known for its horizontal fall and subtle shimmy action. Effective weightless, wacky rigged, Texas rigged, or neko rigged.",
"url": "https://www.example.com/product/5-inch-senko/",
"productGroupID": "517",
"category": "Soft Plastic Fishing Baits",
"brand": {
"@id": "https://www.example.com/#brand-yamamoto"
},
"variesBy": [
"https://schema.org/color"
],
"hasVariant": [
{ "@id": "https://www.example.com/product/5-inch-senko/#variant-greenpumpkin" },
{ "@id": "https://www.example.com/product/5-inch-senko/#variant-watermelon" }
],
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "523",
"bestRating": "5",
"worstRating": "1"
},
"review": [
{
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5"
},
"author": {
"@type": "Person",
"name": "John D."
},
"reviewBody": "Best soft plastic for bass. The action on the fall is unmatched — especially weightless in clear water."
}
]
}
GEO Benefits of ProductGroup
- AI systems group all variants under one canonical entity
- Reviews and ratings consolidate at the parent level (more authoritative)
- Shopping Graph recognizes the product family correctly
- Conversational queries like "best Senko colors" resolve to the right entity
2. hasVariant and isVariantOf
These two properties create an explicit, bidirectional relationship between a ProductGroup and its individual Product variants. Without them, variant relationships must be inferred — and AI systems often get it wrong.
Parent (ProductGroup)
"hasVariant": [
{ "@id": "https://www.example.com/product/5-inch-senko/#variant-greenpumpkin" },
{ "@id": "https://www.example.com/product/5-inch-senko/#variant-watermelon" }
]
Child (Product)
{
"@type": "Product",
"@id": "https://www.example.com/product/5-inch-senko/#variant-greenpumpkin",
"name": "5\" Senko Worm — Green Pumpkin",
"sku": "YAM-5S-GP",
"color": "Green Pumpkin",
"isVariantOf": {
"@id": "https://www.example.com/product/5-inch-senko/#productgroup"
},
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"price": "7.99",
"availability": "https://schema.org/InStock",
"url": "https://www.example.com/product/5-inch-senko/?color=green-pumpkin"
}
}
Rules
- Every variant
Productmust haveisVariantOfpointing to theProductGroup - The
ProductGroupmust list every variant inhasVariant - Bidirectional — both directions must be present for full graph cohesion
3. variesBy
variesBy tells AI systems what dimension changes between variants. Without it, engines guess the variant dimension.
"variesBy": [
"https://schema.org/color"
]
For products that vary by multiple dimensions:
"variesBy": [
"https://schema.org/color",
"https://schema.org/size"
]
Supported schema.org dimension values:
| Product Type | Typical variesBy Values |
|---|---|
| Apparel | color, size |
| Fishing baits | color |
| Electronics | color, storageOption |
| Footwear | color, size |
| Crossbows | color |
| Knives | material, color |
4. Stable @id Values — Absolute URLs
The @id field creates a permanent, machine-readable identifier for every entity. This is one of the most commonly broken areas in product schema.
Rule: Always Use Absolute URLs
// BAD — relative URL, breaks in cached/detached contexts
"@id": "/product/senko/#productgroup"
// GOOD — absolute URL, works everywhere
"@id": "https://www.example.com/product/senko/#productgroup"
Why It Matters
AI crawlers frequently process:
- Detached JSON-LD fragments (scraped or cached)
- Partial page renders (JavaScript-heavy pages)
- Headless browser captures without base URL context
Absolute URLs eliminate ambiguity, improve graph portability, and ensure entities are matched correctly across crawl sessions.
Naming Convention for @id Fragments
Use consistent, predictable fragment patterns:
| Entity | @id Pattern |
|---|---|
| ProductGroup | {canonical-url}#productgroup |
| Product variant | {canonical-url}#variant-{slug} |
| Organization | {site-root}/#organization |
| Brand | {site-root}/#brand-{brand-slug} |
| BreadcrumbList | {page-url}#breadcrumbs |
5. Brand Schema
Brands are first-class entities in AI knowledge graphs. Explicitly declaring brand entities improves product-brand association, Shopping Graph trust, and entity authority.
{
"@type": "Brand",
"@id": "https://www.example.com/#brand-yamamoto",
"name": "Yamamoto",
"url": "https://www.example.com/brands/yamamoto/",
"logo": {
"@type": "ImageObject",
"url": "https://www.example.com/images/yamamoto-logo.png"
}
}
Reference the brand by @id from ProductGroup rather than repeating the full object:
"brand": {
"@id": "https://www.example.com/#brand-yamamoto"
}
6. Offer Schema
Offer supplies pricing, availability, and currency data that AI commerce systems use heavily for shopping answers and product comparisons.
{
"@type": "Offer",
"priceCurrency": "USD",
"price": "7.99",
"availability": "https://schema.org/InStock",
"url": "https://www.example.com/product/5-inch-senko/?color=green-pumpkin",
"priceValidUntil": "2026-12-31",
"itemCondition": "https://schema.org/NewCondition",
"seller": {
"@id": "https://www.example.com/#organization"
}
}
Availability values:
| Value | Meaning |
|---|---|
https://schema.org/InStock | Available to purchase |
https://schema.org/OutOfStock | Currently unavailable |
https://schema.org/PreOrder | Available for pre-order |
https://schema.org/Discontinued | No longer manufactured |
https://schema.org/LimitedAvailability | Low stock |
7. AggregateRating Schema
AggregateRating provides social proof and authority signals that AI systems weight heavily during recommendations and comparisons.
Critical rule: Attach AggregateRating to the ProductGroup, not individual variants. Attaching it to variants splits rating authority.
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "523",
"bestRating": "5",
"worstRating": "1"
}
| Field | Notes |
|---|---|
ratingValue | Average rating as a decimal string |
reviewCount | Total number of reviews |
bestRating | Max possible rating (typically "5") |
worstRating | Min possible rating (typically "1") |
8. Review Schema
Individual reviews provide real-world usage context and consumer sentiment that AI systems summarize when answering recommendation queries.
{
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5"
},
"author": {
"@type": "Person",
"name": "John D."
},
"datePublished": "2026-03-15",
"reviewBody": "Best soft plastic I have ever used. The horizontal fall triggers bites that nothing else will."
}
Embed 3–5 representative reviews in the ProductGroup review array. Prioritize reviews that:
- Mention specific use cases (best for clear water, best weightless)
- Compare to competitor products
- Include technical language (action, sink rate, hook gap)
These review types align most closely with conversational AI queries.
9. AdditionalProperty Schema
Technical attributes are the most GEO-valuable product data you can add. AI systems prefer measurable, objective facts over marketing language.
"additionalProperty": [
{
"@type": "PropertyValue",
"name": "Length",
"value": "5 inches"
},
{
"@type": "PropertyValue",
"name": "Type",
"value": "Soft plastic stick bait"
},
{
"@type": "PropertyValue",
"name": "Best Rigging Methods",
"value": "Wacky Rig, Texas Rig, Neko Rig, Weightless"
},
{
"@type": "PropertyValue",
"name": "Target Species",
"value": "Largemouth Bass, Smallmouth Bass"
},
{
"@type": "PropertyValue",
"name": "Material",
"value": "Salt-impregnated soft plastic"
},
{
"@type": "PropertyValue",
"name": "Sink Rate",
"value": "Slow — horizontal fall"
},
{
"@type": "PropertyValue",
"name": "Recommended Hook Size",
"value": "1/0 to 3/0 wide-gap offset"
}
]
Attributes with the highest GEO value by product type:
| Product Type | High-Value Attributes |
|---|---|
| Fishing baits | length, weight, material, sink rate, target species, hook size, action type |
| Crossbows | draw weight, arrow speed, power stroke, axle-to-axle width, trigger pull |
| Knives | blade length, steel type, blade thickness, edge geometry, handle material |
| Game cameras | resolution, trigger speed, detection range, wireless capability, battery life |
| Hearing protection | NRR rating, frequency response, battery life, Bluetooth range |
| Apparel | material composition, waterproof rating, insulation weight, fit type |
Complete Ecommerce Schema Example
The following example combines all product schema elements into a complete @graph block:
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://www.example.com/#organization",
"name": "Example Baits",
"url": "https://www.example.com",
"logo": {
"@type": "ImageObject",
"url": "https://www.example.com/logo.png"
}
},
{
"@type": "Brand",
"@id": "https://www.example.com/#brand-yamamoto",
"name": "Yamamoto",
"url": "https://www.example.com/brands/yamamoto/"
},
{
"@type": "ProductGroup",
"@id": "https://www.example.com/product/5-senko/#productgroup",
"name": "Yamamoto 5\" Senko 10pk",
"description": "Soft plastic stick bait for bass fishing. Horizontal fall, subtle shimmy action.",
"url": "https://www.example.com/product/5-senko/",
"productGroupID": "517",
"brand": { "@id": "https://www.example.com/#brand-yamamoto" },
"variesBy": ["https://schema.org/color"],
"hasVariant": [
{ "@id": "https://www.example.com/product/5-senko/#variant-greenpumpkin" }
],
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "523"
},
"additionalProperty": [
{ "@type": "PropertyValue", "name": "Length", "value": "5 inches" },
{ "@type": "PropertyValue", "name": "Target Species", "value": "Largemouth Bass, Smallmouth Bass" }
]
},
{
"@type": "Product",
"@id": "https://www.example.com/product/5-senko/#variant-greenpumpkin",
"name": "Yamamoto 5\" Senko — Green Pumpkin",
"sku": "YAM-5S-GP",
"color": "Green Pumpkin",
"isVariantOf": { "@id": "https://www.example.com/product/5-senko/#productgroup" },
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"price": "7.99",
"availability": "https://schema.org/InStock"
}
}
]
}
Common Implementation Mistakes
| Mistake | Impact | Fix |
|---|---|---|
Attaching AggregateRating to individual variants | Fragments review authority | Move to ProductGroup |
Using relative @id values (/product/#group) | Breaks entity matching in cached contexts | Use absolute URLs |
Missing isVariantOf on child products | Breaks bidirectional graph | Add to every variant |
Omitting variesBy | Weakens variant grouping | Add for every ProductGroup with variants |
Missing productGroupID | Reduces Shopping Graph matching confidence | Add the internal product ID |
No additionalProperty | AI falls back to marketing copy | Add measurable technical attributes |
| Schema injected client-side only | AI crawlers may miss it entirely | Render schema in initial HTML (SSR) |