Skip to main content
An attribute is a typed field in the shared catalog, and its type decides what a product can hold for it: a choice from a list, free text, a measurement, or a yes/no flag. Picking the right type matters because it fixes how values are stored and linked, and you can’t change it once the attribute exists.

The attribute record

Every attribute is a ProductAttribute record (id prefix pattr) with a name, a type, and a few flags. Its selectable choices are separate ProductAttributeValue records (id prefix pattrval) that belong to it and are deleted with it.
src/scripts/seed-attributes.ts
The script creates one global single_select attribute with two values. Because no handle is passed, the module derives material from the name.

The five types

The type field takes one of the AttributeType enum values. Each type stores what a product holds in a different way: Only a multi_select attribute can be a variant axis. The other four types describe a product but never shape its variants. A product doesn’t store attribute data on itself. Instead, each value it holds is linked to it through the product to value pivot link, and the shape of that link depends on the type:
  • Select types: the product links to existing values you pick by id
  • Text and unit: attaching creates a new ProductAttributeValue named after the entered content, for example "400", and links it
  • Toggle: the product links to the seeded "true" or "false" value, and no new value is ever created
unit stores the number as the value’s name string. The attribute has no separate unit-of-measure field, so put the unit in the attribute name, for example “Weight (kg)”.

Rules the module enforces

The Product Attribute service adds a few rules on top of the generated CRUD methods:
  • Type is fixed: updateProductAttributes throws when you try to change the type of an existing attribute
  • Handles are derived: a global attribute without a handle gets one from its name, and global select values get one from theirs
  • Handles are unique: attribute handles are unique across the catalog, and value handles are unique per attribute
  • Toggle values are seeded: creating a toggle attribute adds its true (rank 0) and false (rank 1) values

Flags on every attribute

Each attribute carries flags that control where it shows up and how it’s treated: