Traditional Product schema uses 8 to 12 properties. AI agents lean on 20 or more. Here is the property list, the validation rules, and the implementation pattern we use for Shopify stores in 2026.

Most schema markup guides for ecommerce are still written for Google. They list the eight or so Product schema properties that earn you a star rating in the SERP and stop there. That worked for the last decade.
It does not work in 2026.
When an AI agent on ChatGPT, Copilot, or Google AI Mode evaluates whether to recommend your product, it scores against a much wider property set. Shopify's own analysis of its merchant base suggests stores with comprehensive Product schema see materially higher AI shopping inclusion rates. Audits of stores enrolled in Agentic Storefronts but invisible in AI chat surfaces consistently find the same gap: schema present, schema thin.
This post is the property list we use, the validation rules we run, and the implementation pattern we deploy on Shopify (both Liquid and Hydrogen) for clients shipping AI-aware schema in 2026. If you have not yet run our 10-minute discoverability audit, do that first. This post fixes what that audit finds.
Two assumptions used to be safe. They are not anymore.
The first was that schema was nice to have, not essential. A well-written product page with good copy and a clean H1 could rank without elaborate JSON-LD. That is still partly true for Google's classical SERP, but it is no longer true for AI surfaces. AI agents do not browse your page. They consume your feed and your schema, score the result, and decide whether to surface you. If the structured data is missing or thin, the agent has to fall back on prose extraction, which is slower, less reliable, and biased against your product when a competitor has cleaner data.
The second was that the property set was small. Schema.org has been around for over a decade and the same six or seven Product properties (name, description, image, offers, aggregateRating, brand, sku) have been treated as enough. AI agents want richer signal: materials, dimensions, certifications, country of origin, ingredient lists, age group, target gender, fit notes, manufacturing details, sustainability claims. The agent uses these to decide whether your product matches the shopper's intent and to write the explanation it shows the buyer.
The practical bar in 2026 is roughly 20 properties per product, with category-specific extensions on top. Below that, you are at a structural disadvantage against any competitor who has done the work.
Before going beyond, get the baseline right. These properties are required (or strongly recommended) by Google for product rich results and they are the absolute minimum for AI agents too.
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Organic Cotton Crew Neck T-Shirt",
"image": [
"https://cdn.yourstore.com/products/tshirt-front.jpg",
"https://cdn.yourstore.com/products/tshirt-back.jpg"
],
"description": "Heavyweight 240 GSM organic cotton crew neck t-shirt, made in Portugal. GOTS certified. Pre-shrunk. Unisex fit.",
"sku": "TS-ORG-CRW-BLK-M",
"gtin13": "5012345678900",
"brand": {
"@type": "Brand",
"name": "Your Brand"
},
"offers": {
"@type": "Offer",
"url": "https://www.yourstore.com/products/organic-tshirt?variant=42",
"priceCurrency": "EUR",
"price": "39.00",
"priceValidUntil": "2026-12-31",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition",
"shippingDetails": {
"@type": "OfferShippingDetails",
"shippingRate": {
"@type": "MonetaryAmount",
"value": "5.00",
"currency": "EUR"
},
"shippingDestination": {
"@type": "DefinedRegion",
"addressCountry": "FR"
},
"deliveryTime": {
"@type": "ShippingDeliveryTime",
"businessDays": {
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"]
},
"transitTime": {
"@type": "QuantitativeValue",
"minValue": 2,
"maxValue": 4,
"unitCode": "DAY"
}
}
}
}
}Three points on the baseline that are routinely wrong on the Shopify stores we audit.
gtin13 (or gtin12, gtin14, mpn) is missing on roughly 60% of stores. GTIN is how AI agents cluster the same product across multiple merchants. Without it, your product looks like a unique SKU to the agent and gets compared against everything, instead of against the same product on competitor stores where you might offer a better price or faster shipping.
priceValidUntil is often omitted or set to a date in the past. Google ignores expired offers and so do AI agents. Set this dynamically to a date 6 to 12 months out.
shippingDetails is the property most often missing. AI agents weight shipping cost and delivery time heavily because shoppers ask about them in conversation. Without shippingDetails, your product is invisible to "ships to France within 3 days" type queries even if you do exactly that.
The properties below are not all required by Google. Several are extensions, some are recommended-only, and a few are category-specific. AI agents read all of them when they are present.
Material and composition. Use material for textiles, recipeIngredient for food, activeIngredient for cosmetics, chemicalComposition for industrial. This is the property most often missing and the easiest to add.
"material": "100% Organic Cotton (GOTS certified)"Weight, dimensions, and size. Use weight, height, width, depth, and size. Critical for furniture, packaging-sensitive categories, and anything where the shopper asks "does this fit on a 60cm shelf?"
"weight": {
"@type": "QuantitativeValue",
"value": 240,
"unitCode": "GRM"
},
"size": "Medium (M)"Color and color hex. Use color for the name and additionalProperty with name colorHex for the hex code. Color naming is inconsistent across merchants and the hex code lets agents cluster reliably.
Country of origin. Use countryOfOrigin. Increasingly important for shoppers filtering by "Made in EU" or "Made in France" intent.
Manufacturer (when different from brand). Use manufacturer with name and country. White-label and reseller stores routinely conflate this with brand; AI agents penalize the mismatch.
Audience and target. Use audience with audienceType, suggestedAge, suggestedGender. Critical for apparel and toys.
Certifications. Use hasCertification. This is a 2023 schema.org addition and most stores have not added it yet. GOTS, B Corp, OEKO-TEX, organic, fair trade, vegan, all should be explicit, not buried in prose.
"hasCertification": [
{
"@type": "Certification",
"name": "GOTS Organic",
"issuedBy": { "@type": "Organization", "name": "Global Organic Textile Standard" }
}
]Aggregate rating and review count. Use aggregateRating with ratingValue, reviewCount, bestRating. Required if reviews exist. Do not invent these. AI agents cross-check ratings against major review platforms and a fabricated aggregateRating damages trust scoring across your full catalog.
Reviews themselves. Include 3 to 5 actual Review entries with author, datePublished, reviewBody, reviewRating. Agents use the prose to write the explanation of why a product is being recommended.
Use case scenarios via additionalProperty. This is the underused property that gives you the biggest edge. Each additionalProperty is a PropertyValue with name and value, and you can list as many as you want. Use it for use cases, fit notes, occasion, season, care instructions, technical specifications, anything category-specific that does not have a first-class property.
"additionalProperty": [
{
"@type": "PropertyValue",
"name": "Use case",
"value": "Layering, gym, casual wear"
},
{
"@type": "PropertyValue",
"name": "GSM",
"value": "240"
},
{
"@type": "PropertyValue",
"name": "Care",
"value": "Wash cold, tumble dry low, do not bleach"
},
{
"@type": "PropertyValue",
"name": "Fit",
"value": "True to size, unisex"
}
]Return policy. Use hasMerchantReturnPolicy with applicableCountry, returnPolicyCategory, merchantReturnDays, returnMethod, returnFees. This is one of the top three questions AI agents are asked. Surface it explicitly.
"hasMerchantReturnPolicy": {
"@type": "MerchantReturnPolicy",
"applicableCountry": ["FR", "BE", "DE"],
"returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
"merchantReturnDays": 30,
"returnMethod": "https://schema.org/ReturnByMail",
"returnFees": "https://schema.org/FreeReturn"
}Energy and sustainability properties. Use energyEfficiencyEnumeration for appliances. For sustainability claims more broadly, use additionalProperty until schema.org catches up.
Schema that lies is worse than no schema. The errors below are the ones we see most often when auditing Shopify stores, in rough order of how badly they hurt.
Currency mismatch. priceCurrency: "USD" while the offered price is in EUR on a French storefront. Causes the agent to display the wrong price or filter the product out as inconsistent.
Availability that does not match reality. availability: "InStock" while the variant has zero inventory. We see this on a third of multi-variant stores because the schema is generated for the master product and not updated per variant.
Stale priceValidUntil. Date in the past. Treated as expired.
Inflated or fabricated aggregateRating. Most common on stores that recently migrated review apps. The new app has 12 reviews but the schema still claims 348. AI agents cross-check and downrank.
GTIN format errors. Wrong length, alphanumeric characters in a numeric GTIN, leading zeros stripped by JSON serialization. Validate as a string with gtin13 etc., not as a number.
Missing @id. Every Product, Offer, and Brand should have a stable @id URL so agents can dedupe across the graph. Most Shopify stores omit this; it costs you matchability.
Duplicate JSON-LD blocks. Common on Shopify when a theme injects schema and an app also injects schema. The two blocks contradict each other and the agent picks the wrong one. Audit by viewing source and counting application/ld+json blocks per page.
Run all changes through Google's Rich Results Test and schema.org's Schema Markup Validator. Both are free, both will catch the bulk of errors before they ship.
For stores on classic Shopify (Liquid themes), the cleanest approach is a single JSON-LD block in theme.liquid that references metafields and metaobjects for the data the theme does not have natively.
{% if template contains 'product' %}
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"@id": "{{ shop.url }}{{ product.url }}",
"name": {{ product.title | json }},
"description": {{ product.description | strip_html | truncatewords: 120 | json }},
"image": {{ product.images | map: 'src' | json }},
"sku": {{ product.selected_or_first_available_variant.sku | json }},
{% if product.metafields.custom.gtin %}
"gtin13": {{ product.metafields.custom.gtin | json }},
{% endif %}
"brand": {
"@type": "Brand",
"name": {{ product.vendor | json }}
},
{% if product.metafields.custom.material %}
"material": {{ product.metafields.custom.material | json }},
{% endif %}
{% if product.metafields.custom.country_of_origin %}
"countryOfOrigin": {{ product.metafields.custom.country_of_origin | json }},
{% endif %}
"offers": {
"@type": "Offer",
"url": "{{ shop.url }}{{ product.url }}?variant={{ product.selected_or_first_available_variant.id }}",
"priceCurrency": {{ cart.currency.iso_code | json }},
"price": "{{ product.selected_or_first_available_variant.price | money_without_currency | remove: ',' }}",
"availability": "https://schema.org/{% if product.selected_or_first_available_variant.available %}InStock{% else %}OutOfStock{% endif %}",
"itemCondition": "https://schema.org/NewCondition"
}
}
</script>
{% endif %}This is intentionally minimal. Extend it by reading additional metafields for additionalProperty, certifications, reviews, and return policy. Keep one source of truth: if your theme injects schema, kill any schema injected by apps to avoid duplicates.
On Hydrogen and other headless React storefronts, schema is generated in the route loader and injected as a regular <script> tag in the response. The advantage over Liquid is that you have full programmatic control over which properties go in, conditional on data quality.
// app/routes/products.$handle.tsx
export async function loader({ params, context }) {
const { product } = await context.storefront.query(PRODUCT_QUERY, {
variables: { handle: params.handle }
});
const schema = buildProductSchema(product);
return { product, schema };
}
function buildProductSchema(product) {
const schema = {
'@context': 'https://schema.org/',
'@type': 'Product',
'@id': `https://www.yourstore.com/products/${product.handle}`,
name: product.title,
description: product.description,
image: product.images.nodes.map((i) => i.url),
sku: product.variants.nodes[0]?.sku,
brand: { '@type': 'Brand', name: product.vendor },
offers: {
'@type': 'Offer',
priceCurrency: product.priceRange.minVariantPrice.currencyCode,
price: product.priceRange.minVariantPrice.amount,
availability: product.availableForSale
? 'https://schema.org/InStock'
: 'https://schema.org/OutOfStock'
}
};
const additionalProperty = [];
for (const field of product.metafields ?? []) {
if (field?.namespace === 'custom' && field?.value) {
additionalProperty.push({
'@type': 'PropertyValue',
name: field.key,
value: field.value
});
}
}
if (additionalProperty.length > 0) {
schema.additionalProperty = additionalProperty;
}
return schema;
}Render the schema in the route component with dangerouslySetInnerHTML inside a <script type="application/ld+json"> tag, or use a small helper component that handles serialization safely.
If you have an hour: open three of your top products in view-source, count the JSON-LD properties, and write the list of what is missing. Most stores find that they are at 6 to 9 properties when they should be at 20+.
If you have a day: define five metafields that cover the structured attributes your category needs (typically: material, country_of_origin, weight, certifications, use_cases). Populate them for your top 50 SKUs. Update your Liquid or Hydrogen template to surface them in additionalProperty.
If you have a week: roll the schema out to your full catalog, fix the most common validation errors above, and set up an automated check (a daily script that fetches a sample of product pages, parses the JSON-LD, validates against your expected property set) so you catch regressions when your team edits products.
We covered the metafield architecture that makes this scalable in the Shopify Metaobjects and Metafields. Without that data layer, schema is something you maintain manually per product and never finish. With it, schema is a function of structured data and stays correct automatically.
No. The properties AI agents read are a superset of what Google uses. Comprehensive schema works for both. The only thing to watch is that some AI-specific properties (hasCertification, certain additionalProperty patterns) are not yet rendered in Google rich results, but they are read by agents.
No, as long as the values are accurate. Schema.org is the standard both Google and AI agents reference. Properties Google does not currently surface are ignored, not penalized.
The cleanest pattern is one Product for the master with hasVariant references, plus one Offer per variant inside the offers array. On Shopify this requires iterating product.variants in your template. Most themes ship with master-only schema and need updating.
ProductGroup is useful for stores with strong family relationships across products (clothing in multiple colors and sizes). Use it when each variant is meaningfully its own product, with a unique URL. For most Shopify stores where variants share a URL, Product with multiple Offer entries is simpler and equally effective.
Yes. Organization schema on your homepage with name, url, logo, sameAs (your social profiles), and contactPoint gives AI agents a stable brand entity to attach product information to. LocalBusiness only if you have a physical retail presence.
The next post in this series, Shopify Metaobjects and Metafields, goes into the data architecture that lets you populate this schema at scale across thousands of SKUs without manual editing per product.
If you want us to audit your schema and write the implementation plan, get in touch. For complex catalogs we typically run a half-day workshop with your dev team, deliver a property map per category, and ship the Liquid or Hydrogen implementation within two weeks.

On March 24, 2026, Shopify made 5.6 million stores discoverable to AI agents by default. Here is the 10-minute audit we run to tell whether your store is actually getting recommended, or just enrolled.

A senior engineer's hreflang setup guide for Shopify in 2026. When to use Markets vs multi-store, how canonicals interact with hreflang, the validation playbook, and the migration trap nobody warns you about.

A senior engineer's playbook for migrating to Shopify without losing rankings. Redirect mapping logic, metadata preservation, hreflang continuity, and the 30-day post-launch monitoring that catches the issues nobody warns you about.