Skip to main content
Use attributes to give every product in your marketplace the same typed vocabulary, from sizes and materials to capacities and yes/no flags. An attribute is a typed field that operators define once and attach to products in the shared master catalog. It describes products the same way across every store, feeds storefront filters, and, when it’s a variant axis, decides which variants a product can have. The Product Attribute module holds the attributes and their values. Links connect them to Medusa’s products, categories, and product options, so a variant axis is a real Medusa ProductOption underneath. The global attribute catalog lists Size, Material, Thread count, Gift wrap, and Care with their types, and Size is the one variant axis, backed by the global Medusa product option Size behind it. The global attribute catalog lists Size, Material, Thread count, Gift wrap, and Care with their types, and Size is the one variant axis, backed by the global Medusa product option Size behind it.
The data models are ProductAttribute (id prefix pattr) and ProductAttributeValue (id prefix pattrval), resolved with MercurModules.PRODUCT_ATTRIBUTE from @mercurjs/types. Attributes belong to the catalog, never to a store.

Key features

The Product Attribute module covers the full life of a catalog attribute:
  • Five types: single_select, multi_select, text, unit, and toggle, each storing its values differently
  • Variant axes: a multi_select attribute with is_variant_axis creates a Medusa ProductOption that variants bind to
  • Global or inline: define an attribute once for the whole catalog, or create a one-off attribute on a single product
  • Category scoping: link an attribute to product categories so it’s offered only for products in them
  • Storefront filters: shoppers filter products by axis values, and is_filterable tells your storefront which attributes to show as facets
  • One batch workflow: attach, detach, and update all of a product’s attributes in a single run
  • Hooks and events: catalog workflows expose hooks and emit product-attribute.* and product-attribute-value.* events

How it works

An attribute reaches a product in four steps:
  1. An operator runs createProductAttributesWorkflow. For a variant axis, it also creates a global ProductOption with the same values.
  2. A product is created with Mercur’s createProductsWorkflow, or edited with createAndLinkProductAttributesToProductWorkflow, and picks the attributes and values it uses.
  3. Selected values link to the product. For an axis, the product also gets the option with only the selected subset of values.
  4. Variants bind to the axis option by its title, for example { Size: "M" }, and the storefront filters products by those option values.

Get started

Learn how attributes, values, and axes fit together.

Attribute types

The five types and how each one stores its values.

Variant axes

How an axis attribute mirrors a Medusa ProductOption.

Global vs inline

Catalog attributes, product-scoped attributes, categories, and filters.

Examples

Build against attributes in your own server code.

Create an attribute

Run createProductAttributesWorkflow from a route or seed script.

Attach to a product

Attach, detach, and update a product’s attributes in one run.

Create a variant axis

Create an axis and build a product’s variants on it.

Resources

The data models, links, workflows, service methods, and events behind attributes.

Data models

ProductAttribute and ProductAttributeValue, field by field.

Links

Links to products, categories, and product options.

Workflows

Catalog workflows and product attachment workflows.

Service

Module service methods for working with records directly.

Events

Events emitted as attributes and values change.