Facets
Facets turn catalog fields into storefront filter controls. A facet has a customer-facing name, a product or product-variant association, a field to aggregate, and optional rules for which values to expose and how to order them.
Configure facets with the Admin API. Request evaluated facets alongside a Storefront products or productVariants connection. Each Storefront facet includes its display name, typed field, filterable queryField, and the values available in the current result context.
Facets and search use one shared contract: render the returned values, then combine queryField and the selected value into the connection’s query argument. Do not derive dynamic attribute or metafield paths in storefront code.
How facets move through the APIs
| Step | API | Responsibility |
|---|---|---|
| Configure | Admin | Choose the facet name, association, field, visible values, and ordering. |
| Evaluate | Storefront | Apply the current search and commerce context, then return matching facet values. |
| Render | Your storefront | Display the returned facet name and values. |
| Filter | Storefront | Send selected values back through the connection’s query argument. |
Facet definitions are project configuration. The Storefront response is runtime data and can change with the search expression, catalog contents, publication state, store, price context, and customer context.
Configure a facet with the Admin API
Create one definition for each filter group the storefront should present. The example below exposes discovered product vendors under the customer-facing name “Brand.”
AUTOMATIC selects values found in the catalog. You can exclude unwanted values and provide a preferred order for active values.
Inspect both facet and errors in the mutation payload. Invalid field combinations return a typed FacetFieldInvalidError with a reason.
See facetCreate, FacetCreateInput, and FacetFieldInput for the full contract.
Associations
PRODUCTfacets are returned by the Storefrontproductsconnection.PRODUCT_VARIANTfacets are returned by the StorefrontproductVariantsconnection.
Choose the association that matches the result grid being filtered. A variant facet can use product-level vendor, tag, or metafield information where supported, while still aggregating variant results.
Field kinds
| Kind | What it represents | Storefront queryField shape |
|---|---|---|
VENDOR | Product vendor or brand. | vendor or product.vendor |
TAG | Product tags. | tag or product.tags |
ATTRIBUTE | Values of a configured product attribute. | attributes.<normalized-name> |
METAFIELD | Values of an existing public metafield definition. | metafields.<namespace>.<key> or a product-owned variant path |
AVAILABILITY | Whether the result is available for sale. | available_for_sale |
PRICE | The contextual minimum and maximum price. | price |
An ATTRIBUTE facet requires attributeId. A METAFIELD facet requires namespace and key; its owner defaults from the facet association. Product facets can only use product metafields. Namespace, key, and owner are invalid for other facet kinds.
Price and availability facets do not accept value-selection or ordering configuration.
Choose which values appear
Facets with discrete values—vendor, tag, attribute, and metafield—support two selection modes:
| Mode | Use it when | Configuration rules |
|---|---|---|
AUTOMATIC | New catalog values should appear without updating the facet. | Do not set values. Use excludedValues to hide values. |
MANUAL | Only an explicit allowlist should appear. | Set values. Do not set excludedValues. |
Use valueOrder to place important active values first. In automatic mode, ordered values cannot also be excluded. In manual mode, every ordered value must be present in values. Values not named in valueOrder keep a stable position after the configured values.
When valueSelectionMode is omitted, a facet with no explicit values behaves as automatic; a facet with values behaves as manual. Set the mode explicitly in integrations so intent remains clear.
Render and apply Storefront facets
The Storefront response is designed to drive the filter UI directly:
nameis the configured label, such as “Brand.”fieldidentifies the facet kind for type-specific rendering.queryFieldis the exact field name accepted by the search language.valuescontains each available value and its matching result count.
Build a clause from queryField and the chosen value, then combine clauses using the Search query language. For example, a returned queryField of attributes.color and a selected value of Blue produces attributes.color:Blue.
Quote values that contain whitespace or search-language punctuation, for example vendor:"Acme Lighting". Pass the final expression as a GraphQL variable rather than interpolating it into the operation text.
Keep selected filters in application state as { queryField, value } pairs. This avoids hard-coding normalized attribute paths and keeps the UI aligned if an Admin user changes facet configuration.
Price facets are ranges
A price facet is different from a discrete value facet. It returns values named min and max; their count field carries the contextual minimum and maximum amount in integer minor currency units. For EUR, a returned value of 5000 represents EUR 50.00.
Use those bounds to render a range control. Send the selected range back as price:>=<minimum> and price:<=<maximum>, with the same Storefront price currency, channel, country, and customer context used to request the facets.
price:>=5000 AND price:<=15000
For ordinary facet values, count is the number of matching results. Treat the PRICE field as the explicit signal to interpret min and max as amounts instead.
Integration checklist
- Configure the facet once through Admin and handle typed mutation errors.
- Request
facetswith the same Storefront connection, search expression, and commerce context as the product grid. - Render the returned name and values; use
fieldfor specialized controls such as price ranges. - Preserve the returned
queryFieldand use it when constructing filters. - Reset cursor pagination whenever the filter expression changes.
- Re-request both products and facets after a selection so counts and available values stay current.