HomeBlog › Shopify clothing size schema for AI shopping agents

Shopify clothing size schema for AI shopping agents: SizeSpecification, ProductGroup variesBy, and the variant-title trap

2026-06-12 — ~17 min read — SizeSpecificationProductGroupApparel schemaShopify LiquidAI shopping

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.

96%
of Shopify apparel stores have no SizeSpecification in product JSON-LD
#1
most-filtered attribute in AI shopping queries for apparel: size (ahead of colour and price)
3.2×
higher variant click-through when AI result shows available sizes vs. no size information
<30 min
to retrofit SizeSpecification + ProductGroup into a Dawn theme with this guide's snippet

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:

  1. Attempt string extraction — parse the title and guess which part is the size. This is brittle. A store that uses M / Forest Green for apparel might use 5L / Chrome for 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.
  2. 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 SizeSpecification data is more useful to the shopper than one that includes a product whose size the agent has to guess.
  3. 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.

What most Shopify themes output
{
  "@type": "Product",
  "name": "Classic Puffer Jacket",
  "offers": {
    "@type": "Offer",
    "name": "M / Forest Green",
    "price": 129.00
  }
}
What AI agents can parse
{
  "@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:

name
Required. The human-readable size label as it appears on your store — "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.
sizeSystem
Strongly recommended. A 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.
sizeGroup
Strongly recommended. A 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.
suggestedMeasurement
Optional but valuable for international audiences. A 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"
  }
}
URI form vs. short form: Schema.org enumerations like 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)
Do not use 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:

  1. One Product with one Offer — the default Shopify theme approach. The product is represented as a single entity. size is a single value (typically the currently selected variant or the first available). AI agents see one product, not twelve variants.
  2. ProductGroup with hasVariant — the correct approach for multi-variant apparel. The parent ProductGroup declares which attributes vary (variesBy), and each child Product in hasVariant has its own size, color, offers, and availability. 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:

variesBy
Required. An array of schema.org property URIs that differ across variants. Use "https://schema.org/size" and/or "https://schema.org/color". This is what tells AI agents which attributes to use for faceted filtering.
hasVariant
Required. Array of 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?"
@id on ProductGroup
Strongly recommended. A stable URL for the product group node, typically the canonical product URL appended with #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).

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:

  1. In Shopify admin, go to Settings → Custom data → Products and add a metafield definition: namespace custom, key size_group, type Single line text.
  2. Fill in the value for each product: WomenClothing, MenClothing, UnisexClothing, etc. (or use a dropdown list metafield for enforced values).
  3. In the Liquid snippet, replace the hardcoded sizeGroup with: {% 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

Mistake 1
Using bare enumeration names instead of full URIs

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.

Mistake 2
Using 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.

Mistake 3
Outputting only the currently selected variant in 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.

Mistake 4
Outputting variant availability on the parent 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.

Mistake 5
Declaring 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

Does Shopify Dawn output SizeSpecification JSON-LD by default?
No. Dawn outputs a 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.
What is the difference between SizeSpecification and a plain string for size?
A plain string like "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.
What is 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.
Which sizeSystem values does Schema.org support?
Schema.org's 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.
Does CatalogScan check SizeSpecification as part of its AI readiness scan?
Yes. CatalogScan detects products that have a "Size" option in their Shopify data and checks whether the product JSON-LD outputs a 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.

Run a free scan 100-store leaderboard