Home › Blog › Shopify clothing size schema for AI shopping agents
Shopify clothing size schema for AI shopping agents: SizeSpecification, ProductGroup variesBy, and the variant-title trap
When a shopper asks ChatGPT Shopping "women's puffer jacket size medium, under $150" the AI agent resolves "size medium" from SizeSpecification JSON-LD — not from your variant title string. A variant named M / Forest Green is opaque to size filters. A SizeSpecification with sizeSystem: SizeSystemUS and sizeGroup: WomenClothing is not. Over 96% of Shopify apparel stores have no SizeSpecification in their product structured data.
SizeSpecification in product JSON-LDSizeSpecification + ProductGroup into a Dawn theme with this guide's snippetContents
- The variant-title trap: why "M / Forest Green" is invisible to AI agents
- SizeSpecification: anatomy of the schema
- sizeSystem: telling AI agents which measurement scale you use
- sizeGroup: gender, age, and population segments
- ProductGroup and variesBy: the right architecture for multi-variant products
- Liquid implementation for Dawn themes
- Footwear and accessories: SizeSpecification beyond clothing
- Five mistakes that break size schema
- Testing and validation
- FAQ
The variant-title trap: why "M / Forest Green" is invisible to AI agents
Shopify stores every product variant under a title string that concatenates option values — for example, Medium / Forest Green or M / Blue / Cotton. This title appears in Shopify's products.json endpoint, in the Storefront API GraphQL response, and in the Product JSON-LD that most Shopify themes output. It is how Shopify distinguishes variants from one another, and it works for human shoppers who read the title on a product page.
AI shopping agents parsing a product feed do not read variant titles the way a human reads a page. They look for structured, machine-interpretable attributes: a size property with a known type, a color property with a normalised value, a sizeSystem that tells them whether "M" means US Medium, EU 38/40, or UK 12. When the only size signal in your product JSON-LD is a string fragment inside a variant title like Medium / Forest Green, an AI agent has three options:
- Attempt string extraction — parse the title and guess which part is the size. This is brittle. A store that uses
M / Forest Greenfor apparel might use5L / Chromefor a hardware product — "5L" is a size, but not a clothing size, and "Chrome" is a finish, not a colour. AI agents trained across millions of product feeds learn to distrust free-form title parsing for size. - Skip the product from size-filtered results — the safest option when there is no authoritative size signal. A query for "women's jacket size M" that returns only products with confirmed
SizeSpecificationdata is more useful to the shopper than one that includes a product whose size the agent has to guess. - Surface the product but suppress the size badge — the product appears in general results but is excluded from faceted "size M" filter panels that AI shopping interfaces are beginning to expose.
None of these outcomes serves you. Shopify stores that output proper SizeSpecification in their Product JSON-LD get size-filter inclusion, which is a substantial ranking advantage in a category — apparel — where size is the primary qualifying constraint in purchase queries.
{
"@type": "Product",
"name": "Classic Puffer Jacket",
"offers": {
"@type": "Offer",
"name": "M / Forest Green",
"price": 129.00
}
}
{
"@type": "Product",
"name": "Classic Puffer Jacket",
"size": {
"@type": "SizeSpecification",
"name": "M",
"sizeSystem": "https://schema.org/SizeSystemUS",
"sizeGroup": "https://schema.org/WomenClothing"
}
}
SizeSpecification: anatomy of the schema
SizeSpecification is a schema.org type that extends QualitativeValue. It is used as the value of the size property on a Product object. Its four key properties are:
"S", "Medium", "38", "One Size". Use the same value you display to shoppers on the product page. This is what appears in AI result cards and size filter chips.SizeSystemEnumeration URI specifying the sizing scale. Examples: https://schema.org/SizeSystemUS, https://schema.org/SizeSystemEU, https://schema.org/SizeSystemUK. Without this, AI agents cannot normalise your "M" against other stores' "M" values that may use different regional scales.SizeGroupEnumeration URI specifying the population this size applies to. Examples: https://schema.org/WomenClothing, https://schema.org/MenClothing, https://schema.org/KidsClothing, https://schema.org/PlusSizes. This is the field that disambiguates a women's Medium from a men's Medium from a children's Medium — three completely different measurements that share the same label.QuantitativeValue with the physical measurement this size corresponds to — for example, bust circumference in centimetres for a clothing size. This lets AI agents answer "what is a US Medium in cm?" and is especially useful for stores using Shopify Markets to serve customers who expect local measurement units.A complete SizeSpecification for a women's US Medium sweater:
{
"@type": "SizeSpecification",
"name": "M",
"sizeSystem": "https://schema.org/SizeSystemUS",
"sizeGroup": "https://schema.org/WomenClothing",
"suggestedMeasurement": {
"@type": "QuantitativeValue",
"minValue": 86,
"maxValue": 91,
"unitCode": "CMT",
"name": "bust circumference"
}
}
SizeSystemUS and WomenClothing should be expressed as full URI strings — "https://schema.org/SizeSystemUS" — rather than bare names. Bare names are human-readable but are not valid enumeration values in JSON-LD. Google's Rich Results Test and AI crawlers that validate against schema.org will silently ignore an invalid enumeration value, leaving you with no sizeSystem even though the property appears in your markup.
sizeSystem: telling AI agents which measurement scale you use
The same label "M" means something different depending on whether it comes from a US sizing context, a European sizing context, or a Japanese one. A US women's Medium is typically a bust of 86–91 cm; a European 38/40 corresponds to roughly the same measurement; a Japanese M runs smaller. AI agents resolving a cross-store "size medium" query need sizeSystem to normalise these values before returning results.
Schema.org's SizeSystemEnumeration covers all major regional systems:
| Schema.org URI | Region | Typical use |
|---|---|---|
SizeSystemUS |
United States | XS/S/M/L/XL letter sizes and US numeric (2, 4, 6…) for women; S/M/L and waist/inseam for men |
SizeSystemEU |
Europe (general) | Numeric: women 34–46, men 44–56, children 86–164 cm height |
SizeSystemUK |
United Kingdom | Women 6–22, men collar/chest measurements; one size off EU numerics |
SizeSystemIT |
Italy | Women 36–50; men 44–58; luxury fashion default |
SizeSystemFR |
France | Aligns with IT; separate enumeration for brand accuracy |
SizeSystemJP |
Japan | Numeric women 5–17; men S/M/L/LL; runs smaller than Western scales |
SizeSystemAU |
Australia | Women 6–22 (aligns with UK but +2 vs. US) |
SizeSystemBR |
Brazil | PP/P/M/G/GG for apparel; numeric 34–52 |
If your store ships globally via Shopify Markets and uses region-specific size labels (EU sizes for European customers, US sizes for North American customers), the correct approach is to output one SizeSpecification per regional size for each variant — using an array value on the size property — rather than trying to collapse them into a single value. AI agents will select the relevant SizeSpecification based on the shopper's detected locale.
"size": [
{
"@type": "SizeSpecification",
"name": "M",
"sizeSystem": "https://schema.org/SizeSystemUS",
"sizeGroup": "https://schema.org/WomenClothing"
},
{
"@type": "SizeSpecification",
"name": "38/40",
"sizeSystem": "https://schema.org/SizeSystemEU",
"sizeGroup": "https://schema.org/WomenClothing"
},
{
"@type": "SizeSpecification",
"name": "10",
"sizeSystem": "https://schema.org/SizeSystemUK",
"sizeGroup": "https://schema.org/WomenClothing"
}
]
sizeGroup: gender, age, and population segments
sizeGroup is the property that disambiguates sizes across population segments. An AI shopping agent resolving "men's large polo shirt" needs to know that a product's SizeSpecification with name: "L" is a men's large specifically — not a women's large, not a children's large. Schema.org's SizeGroupEnumeration covers:
| Schema.org URI | Segment |
|---|---|
WomenClothing |
Women's adult clothing and apparel |
MenClothing |
Men's adult clothing and apparel |
KidsClothing |
General children's clothing (use with BoysClothing / GirlsClothing for gender-specific) |
BoysClothing |
Boys' clothing — more specific than KidsClothing |
GirlsClothing |
Girls' clothing |
InfantsClothing |
Babies and infants (0–24 months) |
UnisexClothing |
Gender-neutral sizing — not a fallback for "unknown", but an explicit unisex declaration |
Adults |
Unisex adult; use when your product genuinely fits both men and women using the same size chart |
PlusSizes |
Plus-size apparel (typically women's 1X–4X or equivalent) |
Petite |
Petite women's sizing (shorter inseam, proportionally smaller cuts) |
Maternity |
Maternity clothing |
Tall |
Tall apparel (longer inseam/torso) |
Adults as a fallback for "I'm not sure." Adults (also expressed as the URI https://schema.org/Adults) is a specific declaration that your product is sized for adult use with no gender distinction. A men's dress shirt is not Adults — it is MenClothing. Using Adults as a catch-all for adult products will cause AI agents to exclude your products from gender-specific queries ("men's shirts in size L") because the signal explicitly says unisex.
ProductGroup and variesBy: the right architecture for multi-variant products
Most Shopify stores have multi-variant products: one item available in three sizes and four colours is twelve purchasable variants under one product. In Product JSON-LD, there are two ways to represent this:
- One
Productwith oneOffer— the default Shopify theme approach. The product is represented as a single entity.sizeis a single value (typically the currently selected variant or the first available). AI agents see one product, not twelve variants. ProductGroupwithhasVariant— the correct approach for multi-variant apparel. The parentProductGroupdeclares which attributes vary (variesBy), and each childProductinhasVarianthas its ownsize,color,offers, andavailability. AI agents can now present size/colour filter chips and per-variant availability in result cards.
The ProductGroup schema structure for a product varying by size and colour:
{
"@context": "https://schema.org",
"@type": "ProductGroup",
"@id": "https://yourstore.com/products/classic-puffer-jacket#group",
"name": "Classic Puffer Jacket",
"description": "Insulated puffer jacket in recycled ripstop fabric.",
"url": "https://yourstore.com/products/classic-puffer-jacket",
"brand": {
"@type": "Brand",
"name": "YourBrand"
},
"variesBy": [
"https://schema.org/size",
"https://schema.org/color"
],
"hasVariant": [
{
"@type": "Product",
"@id": "https://yourstore.com/products/classic-puffer-jacket?variant=1001",
"name": "Classic Puffer Jacket — M / Forest Green",
"sku": "CPJ-M-FG",
"size": {
"@type": "SizeSpecification",
"name": "M",
"sizeSystem": "https://schema.org/SizeSystemUS",
"sizeGroup": "https://schema.org/WomenClothing"
},
"color": "Forest Green",
"image": "https://yourstore.com/cdn/shop/products/cpj-m-fg.jpg",
"offers": {
"@type": "Offer",
"price": 129.00,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"url": "https://yourstore.com/products/classic-puffer-jacket?variant=1001"
}
},
{
"@type": "Product",
"@id": "https://yourstore.com/products/classic-puffer-jacket?variant=1002",
"name": "Classic Puffer Jacket — L / Forest Green",
"sku": "CPJ-L-FG",
"size": {
"@type": "SizeSpecification",
"name": "L",
"sizeSystem": "https://schema.org/SizeSystemUS",
"sizeGroup": "https://schema.org/WomenClothing"
},
"color": "Forest Green",
"image": "https://yourstore.com/cdn/shop/products/cpj-l-fg.jpg",
"offers": {
"@type": "Offer",
"price": 129.00,
"priceCurrency": "USD",
"availability": "https://schema.org/OutOfStock",
"url": "https://yourstore.com/products/classic-puffer-jacket?variant=1002"
}
}
]
}
The key properties on ProductGroup:
"https://schema.org/size" and/or "https://schema.org/color". This is what tells AI agents which attributes to use for faceted filtering.Product objects — one per purchasable variant. Each variant must have its own offers with variant-level availability (InStock, OutOfStock) and a url with the ?variant= parameter. AI agents use per-variant availability to answer "is size L in stock?"#group. This allows AI agents to reference the group entity and cross-link your product group to external knowledge graphs (e.g., brand Product entities in Google Knowledge Graph).Related guides
Liquid implementation for Dawn themes
Dawn and its descendants generate Product JSON-LD in snippets/structured-data.liquid. Look for the render 'structured-data' call in sections/main-product.liquid. The snippet outputs a single Product object — you will extend it to add size with SizeSpecification per variant, and optionally restructure to ProductGroup for multi-variant products.
Step 1: Add SizeSpecification to the existing Product block
The quickest path for a store that already has a Product JSON-LD block is to add a size property that outputs a SizeSpecification for the currently selected (or first available) variant. This does not require restructuring to ProductGroup — it adds the size signal without breaking your existing schema.
Find the JSON-LD block for your product in snippets/structured-data.liquid and add a "size" property inside the Product object. The snippet below detects the "Size" option (case-insensitive) and outputs a SizeSpecification if present. Replace the sizeSystem and sizeGroup values to match your store's sizing:
{% comment %} SizeSpecification — add inside the Product @type block {% endcomment %}
{% assign size_option_index = nil %}
{% for option in product.options %}
{% if option downcase == "size" %}
{% assign size_option_index = forloop.index0 %}
{% endif %}
{% endfor %}
{% if size_option_index != nil %}
{% assign current_size = product.selected_or_first_available_variant.options[size_option_index] %}
{% unless current_size == blank %}
,"size": {
"@type": "SizeSpecification",
"name": {{ current_size | json }},
"sizeSystem": "https://schema.org/SizeSystemUS",
"sizeGroup": "https://schema.org/WomenClothing"
}
{% endunless %}
{% endif %}
Replace SizeSystemUS and WomenClothing with values appropriate for your store. For a store with multiple sizeGroup values (a brand selling both women's and men's), you need to determine the sizeGroup dynamically — typically from a product metafield (product.metafields.custom.size_group) or from the product type.
Step 2: Add ProductGroup with all variants (recommended for apparel)
For apparel stores with multi-variant products, the full ProductGroup implementation is significantly more valuable than the single-variant shortcut. It gives AI agents per-variant availability and a complete size range for filter chips. This requires replacing the single Product output in your structured data snippet with a ProductGroup wrapper.
Here is a complete Liquid snippet for Dawn that outputs a ProductGroup with hasVariant for every variant. Place this in snippets/structured-data.liquid, replacing the existing Product JSON-LD block for apparel product types:
{% comment %}
ProductGroup with SizeSpecification — for apparel products with a "Size" option.
Falls back to a plain Product block for products without a Size option.
{% endcomment %}
{% assign has_size_option = false %}
{% assign size_option_index = nil %}
{% for option in product.options %}
{% if option downcase == "size" %}
{% assign has_size_option = true %}
{% assign size_option_index = forloop.index0 %}
{% endif %}
{% endfor %}
{% if has_size_option %}
{% endif %}
Making sizeGroup dynamic with metafields
The snippet above hardcodes WomenClothing as the sizeGroup. For stores with both men's and women's products, you need to supply this value per-product. The cleanest approach is a product metafield:
- In Shopify admin, go to Settings → Custom data → Products and add a metafield definition: namespace
custom, keysize_group, typeSingle line text. - Fill in the value for each product:
WomenClothing,MenClothing,UnisexClothing, etc. (or use a dropdown list metafield for enforced values). - In the Liquid snippet, replace the hardcoded
sizeGroupwith:{% raw %}{{ product.metafields.custom.size_group | default: "Adults" }}{% endraw %}
Using the metafield default of Adults (the schema.org unisex adult enumeration) ensures that products without a size_group metafield still output a valid, if less specific, sizeGroup value rather than omitting the field entirely.
Footwear and accessories: SizeSpecification beyond clothing
SizeSpecification is not clothing-only. Schema.org designed it for any product category where fit dimensions determine purchase decisions. For Shopify stores selling footwear and accessories, the same implementation applies with category-appropriate sizeSystem and sizeGroup values.
Footwear
For shoes and boots, sizeGroup values include WomenFootwear, MenFootwear, and KidsFootwear (from Google's merchant feed extension to schema.org's footwear sizeGroup). The sizeSystem for US shoe sizes is still SizeSystemUS. EU shoe sizes (typically 36–48) use SizeSystemEU. For footwear, suggestedMeasurement in centimetres (foot length) is especially valuable for international stores because shoe size numbering varies significantly by region and has no standard correspondence.
Accessories (belts, hats, rings)
For accessories where the size is a physical measurement (belt length in inches, hat circumference in cm, ring diameter in mm), suggestedMeasurement is the primary signal. Use a QuantitativeValue with the appropriate unitCode: INH for inches, CMT for centimetres, MMT for millimetres. The name property should still match your label ("S", "7", "Medium").
For one-size-fits-most products (scarves, hats with a single universal size), declare a SizeSpecification with "name": "One Size" and omit sizeSystem and sizeGroup. This explicitly signals to AI agents that the product has no size constraint, which is better than omitting the size property entirely — the latter creates ambiguity about whether the product has sizes or the data is simply missing.
Five mistakes that break size schema
Writing "sizeSystem": "SizeSystemUS" or "sizeGroup": "WomenClothing" as plain strings is not valid JSON-LD. These values must be full URIs: "https://schema.org/SizeSystemUS" and "https://schema.org/WomenClothing". The schema.org validator will accept the plain-string form without error, but AI crawlers that validate against the JSON-LD spec will ignore them because bare names are not resolvable URIs in a JSON-LD context that uses the schema.org namespace.
Adults as a fallback for "I don't know the sizeGroup"
Adults (as in https://schema.org/Adults) is a specific unisex declaration. A men's XL hoodie is not Adults — it is MenClothing. If you use Adults as a default for every product, AI agents will exclude your men's and women's products from gender-specific filtered queries. Better to omit sizeGroup entirely for products where you are uncertain, rather than declare an incorrect value.
size, not all variants in ProductGroup
If your structured data only includes the variant that happens to be selected (or first) when the page is crawled, AI agents see one size for the product — not the full size range. A crawler that hits your product page with size M selected will record a product with only size M available. Customers searching for L, XL, or XS will not see your product in size-filtered results. The fix is ProductGroup with hasVariant containing every variant and its per-variant availability.
Product instead of per-variant
A product with 5 variants, 3 of which are out of stock, should not have "availability": "InStock" on the parent Product object. The parent availability should be the worst-case aggregate, or the Product node should not have availability at all — availability belongs on the Offer inside each hasVariant Product. AI agents that read the parent-level InStock and then encounter an out-of-stock variant at checkout will learn to distrust your availability data.
variesBy on ProductGroup without populating the property on each variant
If you declare "variesBy": ["https://schema.org/size"] on a ProductGroup but then omit the size property on the child Product variants, AI agents will flag the schema as inconsistent. The variesBy declaration is a promise that every item in hasVariant will have the declared property. Validate every variant in your hasVariant array against your variesBy list before deploying.
Testing and validation
After adding SizeSpecification and ProductGroup to your theme, use these tools to verify the implementation:
1. Google Rich Results Test
Visit Google's Rich Results Test and enter a product URL. For a ProductGroup implementation, look for the ProductGroup result type and expand hasVariant — each variant should appear with its size block containing SizeSpecification properties. The validator will surface missing required fields and mismatched types.
2. schema.org JSON-LD validator
Paste your rendered JSON-LD into validator.schema.org. Look specifically for the sizeSystem and sizeGroup values — confirm they resolve as valid URIs from the SizeSystemEnumeration and SizeGroupEnumeration types, not as free-form text values.
3. Manual Liquid output inspection
On a product page with many variants, right-click and "View Page Source", then search for "@type": "ProductGroup" or "@type": "SizeSpecification". Check that every expected variant appears in hasVariant, that each has a unique @id with the correct ?variant= parameter, and that no Liquid whitespace errors have broken the JSON structure. An unclosed brace or misplaced comma in Liquid-generated JSON produces a silent parse failure — the entire structured data block is dropped.
4. CatalogScan
CatalogScan's AI readiness scan checks the size signal as part of its 18-signal audit for stores whose product types or variant options suggest apparel or footwear. It flags products with a "Size" option name that output only a plain string in name (the variant title trap), products with no sizeSystem declared, and multi-variant products missing a ProductGroup wrapper. Run a free scan to see your store's size schema score and get the top-5 fixes ranked by estimated AI-agent reach impact. For a deeper look at how structured data audits work, see our guide on Shopify structured data audit tools.
FAQ
SizeSpecification JSON-LD by default?Product JSON-LD block that includes the product name, description, and an Offer — but no size property and no SizeSpecification. The variant title (e.g., "M / Forest Green") appears only inside the Offer.name field, which AI agents do not use for size filtering. You need to add SizeSpecification manually via the snippet approach in this guide.SizeSpecification and a plain string for size?"M" is ambiguous — it could be US Medium, EU 38/40, JP 9, or a children's size depending on context and brand. SizeSpecification adds the machine-readable context that removes that ambiguity: sizeSystem specifies the measurement scale, and sizeGroup specifies the population segment. An AI agent filtering "women's medium jackets" can match SizeSpecification with sizeGroup: WomenClothing and name: M reliably; it cannot confidently match a plain "M" string that might belong to a men's or unisex product.ProductGroup variesBy and why does it matter for AI agents?ProductGroup is a schema.org type representing a family of closely related products (the same item in different sizes, colours, or materials). variesBy declares which properties differ across the group — typically "https://schema.org/size" and/or "https://schema.org/color". AI shopping agents use ProductGroup to understand that your 20-variant jacket is one product with 20 purchasable options, not 20 unrelated products. Without ProductGroup, the agent cannot offer "show me all sizes" navigation and cannot filter "is this in stock in XL?" against your data.sizeSystem values does Schema.org support?SizeSystemEnumeration includes: SizeSystemUS, SizeSystemEU, SizeSystemUK, SizeSystemIT, SizeSystemFR, SizeSystemJP, SizeSystemDE, SizeSystemBR, SizeSystemMX, SizeSystemAU, and SizeSystemCN. Always use the full URI form — for example "https://schema.org/SizeSystemUS". If your store uses a proprietary sizing scale (small/medium/large with no standard regional mapping), either omit sizeSystem or use suggestedMeasurement in centimetres as a fallback that AI agents can normalise.SizeSpecification as part of its AI readiness scan?SizeSpecification with sizeSystem and sizeGroup. Products that rely on variant title strings for size information are flagged as missing the size signal. The scan also checks whether apparel products use ProductGroup with variesBy for multi-variant products. Run a free scan to see your store's size schema status.Is your apparel store missing size schema?
CatalogScan checks all 18 AI readiness signals — including SizeSpecification and ProductGroup — in under 60 seconds.