Configurable Features

Configurable features are features that can be customized by the user. They can be multiple choice, toggles, or numeric ranges.

You can list these features with the configurableFeatures query:

configurableFeatures(
first: Int!,
after: String,
orderBy: ProductConfigurableFeaturesOrderBy
): ProductConfigurableFeatureConnection

This query returns a paginated connection of ProductConfigurableFeature nodes:

interface ProductConfigurableFeature {
"The label of the feature for which this configuration applies."
label: String!
displayName: String!
type: ProductFeatureType!
}

Note that is ProductConfigurableFeature an interface. This interface is implemented by several different feature types:

type ProductBooleanConfigurableFeature implements ProductConfigurableFeature {
label: String!
displayName: String!
type: ProductFeatureType!
featureOptions: [ProductConfigurableFeatureOption!]
}
type ProductNumberConfigurableFeature implements ProductConfigurableFeature {
label: String!
displayName: String!
type: ProductFeatureType!
numericOptions: [ProductConfigurableFeatureNumericOptions!]
}
type ProductStringConfigurableFeature implements ProductConfigurableFeature {
label: String!
displayName: String!
type: ProductFeatureType!
featureOptions: [ProductConfigurableFeatureOption!]
}

Since the query returns the interface, in order to access the underlying type, you'll need to use the GraphQL interface semantics:

{
product(label:"my-product") {
configurableFeatures(first:10) {
edges {
node {
displayName
type
... on ProductStringConfigurableFeature {
displayName
featureOptions {
displayName
value
cost
}
}
... on ProductBooleanConfigurableFeature {
displayName
featureOptions {
value
cost
}
}
... on ProductNumberConfigurableFeature {
displayName
numericOptions {
numericDetails {
min
max
unit
}
}
}
}
}
}
}
}

The way this works is that depending on the underlying type of feature, the result of the query will use the correct fields for it. For example, the options shown in the screenshot at the top of this page would return this for the above query:

{
"data": {
"product": {
"configurableFeatures": {
"edges": [
{
"node": {
"displayName": "Multiple choice feature",
"type": "STRING",
"featureOptions": [
{
"value": "none",
"displayName": "Free",
"cost": 0
},
{
"value": "option-a",
"displayName": "Option A",
"cost": 1000
},
{
"value": "option-b",
"displayName": "Option B",
"cost": 5000
}
]
}
},
{
"node": {
"displayName": "Range feature",
"type": "NUMBER",
"numericOptions": [
{
"numericDetails": {
"min": 1,
"max": 10,
"unit": "TB"
}
}
]
}
},
{
"node": {
"displayName": "Toggle feature",
"type": "BOOLEAN",
"featureOptions": [
{
"value": "true",
"cost": 5000
},
{
"value": "false",
"cost": 0
}
]
}
}
]
}
}
}
}

Note the different fields for each feature type, in particular the "Range feature."

ProductConfigurableFeatureOption

Field

Description

value

The value of the feature when this option is selected (e.g. "0" or "none" or "free-plan")

displayName

The visible title or name of this option (e.g. "Free plan")

cost

The cost associated with this option

ProductConfigurableFeatureNumericOptions

Field

Description

label

displayName

numericDetails

ProductConfigurableFeatureNumericDetails

Field

Description

min

The minimum value the user can pick of this option

max

The maximum value the user can pick for this option

unit

The unit the values refer to (e.g. "GB", "users")

costTiers

A list of available cost tiers

Cost Tiers

Field

Description

limit

The max number of units (see above) for this tier

cost

This feature's cost per unit