multi_select attributes, they can drive variant generation. This tutorial sets up the two kinds that matter most: a plain filterable attribute and a variant axis, which under the hood is a native Medusa global product option.
A variant axis IS a product option. Attributes marked
is_variant_axis aren’t a parallel system bolted onto products — each one mirrors one-to-one onto a Medusa ProductOption and its values. Variants are then built with Medusa’s standard machinery (variants[].options), exactly as in a plain Medusa project. Non-axis attributes never become options; they attach as plain value links. This is why only multi_select attributes can be axes — an axis needs an enumerable set of values to combine into variants.What you’ll build
- A global
Materialattribute (multi-select, filterable) used for storefront filtering. - A global
Colorvariant axis shared across the catalog. - An inline, product-scoped
Fitaxis created on the fly from a product form.
Global vs product-scoped
| Kind | Backed by | Appears in the global catalog? | Use for |
|---|---|---|---|
| Global attribute | Shared ProductOption (when axis) or value links | Yes | Data every product can use — Material, Color, Condition |
| Product-scoped attribute | Exclusive, product-owned option (when axis) | No | One-off fields or axes for a single product |
Build the attribute catalog
Create a filterable attribute
In the Admin Panel, the operator owns the attribute catalog. Create Material as a global
multi_select attribute with values like Cotton, Wool, Linen, and turn on is_filterable. Global attributes (product_id = null) can be attached to any product and linked to categories so the right attributes surface for the right product types.Since it’s not a variant axis, Material describes the product — it will never generate variants.Create a variant axis
Create Color the same way, but enable
is_variant_axis. This is only allowed for multi_select attributes — the platform rejects the flag on any other type.Because Color is a global axis, it’s backed by one shared product option. Every product that uses it links to that option, restricted to the subset of values the product actually offers — so “Color” means the same thing across the whole catalog, while one product can offer only Red and Blue.Attach attributes to a product
Products manage attributes through one batch endpoint that adds, removes, and updates in a single request:At product create time, the same entry shape is passed as a unified
attributes[] array. Because Color is an axis, selecting Red and Blue makes them available as variant options — variants are then defined with standard Medusa variants[].options mapping "Color" to "Red" or "Blue".Add an inline product-scoped axis
Sometimes one product needs an axis that doesn’t belong in the shared catalog. Define it inline by This creates a product-scoped attribute on the fly, backed by an exclusive, product-owned option. It won’t appear in the global attribute list — it belongs to this product alone.
title instead of referencing an id:Attribute changes on products submitted by vendors flow through the same change-request pipeline as other product edits —
ATTRIBUTE_ADD / ATTRIBUTE_UPDATE / ATTRIBUTE_REMOVE actions the operator reviews.Verify
- Material and Color appear in the Admin Panel’s attribute catalog; Fit does not (it’s product-scoped).
- The product detail shows Material as descriptive data and Color/Fit as variant axes.
- The product’s variants combine the selected Color and Fit values, built from real product options.
- The Store API exposes Material for filtering on product listings (
is_filterable).
FAQ
Why can't a text or toggle attribute be a variant axis?
Why can't a text or toggle attribute be a variant axis?
An axis needs an enumerable, finite value set to combine into variants — Red/Blue × Slim/Regular. Free text has no enumerable values, and a toggle’s two fixed values rarely describe purchasable variations. Only
multi_select qualifies, and the platform enforces it.What's the difference between a value link and an option?
What's the difference between a value link and an option?
Non-axis attributes attach to a product as plain value links — descriptive data for display and filtering. Axis attributes are mirrored onto real Medusa product options, which participate in variant generation. Same authoring UI, structurally different underneath.
Can I promote a product-scoped attribute to a global one later?
Can I promote a product-scoped attribute to a global one later?
Not automatically — a product-scoped axis is backed by an exclusive option owned by that product. Create the global attribute in the catalog and re-attach products to it; treat inline attributes as intentionally local.
Next steps
Product Attributes
Types, fields, and the full attribute-to-option mapping.
Master products & offers
How sellers list against the variants your axes generate.