> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Dealing with Product Options

Plan: Composable Developer

Lesson 21 of 27 · 30 min

In the simple storefront you've been building in the previous lab exercises, only simple products are supported. When products offer variant options, more complexity is involved. In this section, we'll look at the key concepts involved with this scenario.

Supporting product options in your storefront involves two main concerns: Offering an appropriate UI for selecting options in your **catalog pages** and accounting for these options in **cart management**.

## Supporting Options in Catalog Pages

The available options on a product - whether those are Variant or Modifier options - can be inspected with the `productOptions` field on a product. This includes the option and value IDs and labels .

### Example Query

```graphql showLineNumbers={false}
query VariantsAndOptionsExample($path: String!) {
  site {
    route(path: $path) {
      node {
        ... on Product {
          productOptions {
            edges {
              node {
                entityId
                displayName
                isRequired
                isVariantOption
              }
            }
          }
        }
      }
    }
  }
}
```

The specific details that can be inspected about an option depend on its type.

See the following example that includes inspecting the values of any multiple choice type option.

```graphql showLineNumbers={false}
query VariantsAndOptionsExample($path: String!) {
  site {
    route(path: $path) {
      node {
        ... on Product {
          productOptions {
            edges {
              node {
                __typename
                ... on MultipleChoiceOption{
                  values{
                    edges{
                      node{
                        entityId
                        label
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
```

With these details, you can craft the appropriate form inputs for any type of product option. Below is a simple example of a possible implementation that supports multiple choice options, based on the format of the above query.

```js showLineNumbers={false}
const ProductForm = ({ product }) => {
  const getOptionByType = (node) => {
    switch (node.__typename) {
      case 'MultipleChoiceOption':
        return (
          <select id={`option-${node.entityId}`}>
            {node.values.edges.map(val => (
              <option value={val.node.entityId}>{val.node.label}</option>
            ))}
          </select>
        )
      default:
        return '';
    }
  }

  return (
    <form>
      {product.productOptions.edges.map(option => (
        <div>
          <label for={`option-${option.node.entityId}`}>{option.node.displayName}</label>
          {getOptionByType(option.node)}
        </div>
      ))}
    </form>
  )
}
```

## Supporting Options in the Cart

With the proper form inputs in place on your catalog pages to capture a shopper's option selections, you can add option and value IDs to the inputs of the `createCart` and `addCartLineItems` mutations to support configured options in a cart.

### Example Mutation with Option:

```graphql showLineNumbers={false}
mutation AddToCart($cartId: String!, $productId: Int!, $optionId: Int!, $valueId: Int!, $qty: Int!) {
  cart {
    addCartLineItems(
      input: {cartEntityId: $cartId,
        data: {
          lineItems: [
            {
              quantity: $qty,
              productEntityId: $productId,
              selectedOptions: {
                multipleChoices: [
                  {
                    optionEntityId: $optionId,
                    optionValueEntityId: $valueId
                  }
                ]
              }
            }
          ]
        }
      }
    ) {
      cart {
        ...
      }
    }
  }
}
```

Notice in the above example that the given option selection is expressed on `selectedOptions.multipleChoices`. This input is specific to the type for a multiple choice option. Modifier options can, of course, be of other types, and each has their own input schema. Review the API reference for the `selectedOptions`type for more information.

By the same token, when querying data about cart items, there is unique schema for each option type. Inspect these details on cart items to show the full context of the shopper's configured options on the cart page.

```graphql showLineNumbers={false}
query GetCart($cartId: String!) {
  site {
    cart(entityId: $cartId) {
      lineItems {
        physicalItems {
          productEntityId
          selectedOptions {
            entityId
            name
            ... on CartSelectedMultipleChoiceOption {
              valueEntityId
              value
            }
          }
        }
      }
    }
  }
}
```

This particular example queries fields specific to `CartSelectedMultipleChoiceOption`. Review the API reference for `CartSelectedOption` for the other sub-types.

## Working with Variant Records

Dealing directly with options, as shown in the examples above, is the most common way of accounting for product variation in a storefront. From a shopper's perspective, options are what drive the experience.

Note, however, that you can also query and interact directly with product variant IDs rather than dealing with options and their values. See the details of the [`Product`](/developer/api-reference/graphql/storefront#definition-Product), [`CartItem`](/developer/api-reference/graphql/storefront#definition-CartPhysicalItem), and [`CartLineItemInput`](/developer/api-reference/graphql/storefront#definition-CartLineItemInput).

## Resources

* [Cart Selected Multiple Choice Option Input](/developer/api-reference/graphql/storefront#definition-CartSelectedMultipleChoiceOptionInput)
* [Selected Options type](/developer/api-reference/graphql/storefront#definition-CartSelectedOptionsInput)
* [Product type](/developer/api-reference/graphql/storefront#definition-Product)
* [CartPhysicalItem type](/developer/api-reference/graphql/storefront#definition-CartPhysicalItem)
* [CartLineItemInput](/developer/api-reference/graphql/storefront#definition-CartLineItemInput)