---
title: getProductOptions
description: >-
  Returns a product options array with its relevant information about the
  variant. This function supports combined listing products and products with
  2000 variants limit.
api_version: 2025-05
api_name: hydrogen
source_url:
  html: 'https://shopify.dev/docs/api/hydrogen/2025-05/utilities/getproductoptions'
  md: 'https://shopify.dev/docs/api/hydrogen/2025-05/utilities/getproductoptions.md'
---

# get​Product​Options

Returns a product options array with its relevant information about the variant. This function supports combined listing products and products with 2000 variants limit.

Examples

### Examples

* #### Example code

  ##### Description

  I am the default example

  ##### JavaScript

  ```jsx
  import React from 'react';
  import {getProductOptions} from '@shopify/hydrogen';

  // Make sure you are querying for the following fields:
  // - product.handle
  // - product.encodedVariantExistence
  // - product.encodedVariantAvailability
  // - product.options.name
  // - product.options.optionValues.name
  // - product.options.optionValues.firstSelectableVariant
  // - product.selectedOrFirstAvailableVariant
  // - product.adjacentVariants
  //
  // For any fields that are ProductVariant type, make sure to query for:
  // - variant.product.handle
  // - variant.selectedOptions.name
  // - variant.selectedOptions.value

  export default function ProductForm() {
    const product = {
      /* Result from querying the SFAPI for a product */
    };

    const productOptions = getProductOptions(product);

    return (
      <>
        {productOptions.map((option) => (
          <div key={option.name}>
            <h5>{option.name}</h5>
            <div>
              {option.optionValues.map((value) => {
                const {
                  name,
                  handle,
                  variantUriQuery,
                  selected,
                  available,
                  exists,
                  isDifferentProduct,
                  swatch,
                } = value;

                if (isDifferentProduct) {
                  // SEO - When the variant is a
                  // combined listing child product
                  // that leads to a different url,
                  // we need to render it
                  // as an anchor tag
                  return (
                    <a
                      key={option.name + name}
                      href={`/products/${handle}?${variantUriQuery}`}
                      style={{
                        border: selected
                          ? '1px solid black'
                          : '1px solid transparent',
                        opacity: available ? 1 : 0.3,
                      }}
                    >
                      <ProductOptionSwatch swatch={swatch} name={name} />
                    </a>
                  );
                } else {
                  // SEO - When the variant is an
                  // update to the search param,
                  // render it as a button with
                  // javascript navigating to
                  // the variant so that SEO bots
                  // do not index these as
                  // duplicated links
                  return (
                    <button
                      type="button"
                      key={option.name + name}
                      style={{
                        border: selected
                          ? '1px solid black'
                          : '1px solid transparent',
                        opacity: available ? 1 : 0.3,
                      }}
                      disabled={!exists}
                      onClick={() => {
                        if (!selected) {
                          // Navigate to `?${variantUriQuery}`
                        }
                      }}
                    >
                      <ProductOptionSwatch swatch={swatch} name={name} />
                    </button>
                  );
                }
              })}
            </div>
            <br />
          </div>
        ))}
      </>
    );
  }

  function ProductOptionSwatch({swatch, name}) {
    const image = swatch?.image?.previewImage?.url;
    const color = swatch?.color;

    if (!image && !color) return name;

    return (
      <div
        aria-label={name}
        className="product-option-label-swatch"
        style={{
          backgroundColor: color || 'transparent',
        }}
      >
        {!!image && <img src={image} alt={name} />}
      </div>
    );
  }
  ```

  ##### TypeScript

  ```tsx
  import React from 'react';
  import {
    getProductOptions,
    type MappedProductOptions,
  } from '@shopify/hydrogen';
  import type {
    ProductOptionValueSwatch,
    Maybe,
  } from '@shopify/hydrogen/storefront-api-types';

  // Make sure you are querying for the following fields:
  // - product.handle
  // - product.encodedVariantExistence
  // - product.encodedVariantAvailability
  // - product.options.name
  // - product.options.optionValues.name
  // - product.options.optionValues.firstSelectableVariant
  // - product.selectedOrFirstAvailableVariant
  // - product.adjacentVariants
  //
  // For any fields that are ProductVariant type, make sure to query for:
  // - variant.product.handle
  // - variant.selectedOptions.name
  // - variant.selectedOptions.value

  export default function ProductForm() {
    const product = {
      /* Result from querying the SFAPI for a product */
    };

    const productOptions: MappedProductOptions[] = getProductOptions(product);

    return (
      <>
        {productOptions.map((option) => (
          <div key={option.name}>
            <h5>{option.name}</h5>
            <div>
              {option.optionValues.map((value) => {
                const {
                  name,
                  handle,
                  variantUriQuery,
                  selected,
                  available,
                  exists,
                  isDifferentProduct,
                  swatch,
                } = value;

                if (isDifferentProduct) {
                  // SEO - When the variant is a
                  // combined listing child product
                  // that leads to a different url,
                  // we need to render it
                  // as an anchor tag
                  return (
                    <a
                      key={option.name + name}
                      href={`/products/${handle}?${variantUriQuery}`}
                      style={{
                        border: selected
                          ? '1px solid black'
                          : '1px solid transparent',
                        opacity: available ? 1 : 0.3,
                      }}
                    >
                      <ProductOptionSwatch swatch={swatch} name={name} />
                    </a>
                  );
                } else {
                  // SEO - When the variant is an
                  // update to the search param,
                  // render it as a button with
                  // javascript navigating to
                  // the variant so that SEO bots
                  // do not index these as
                  // duplicated links
                  return (
                    <button
                      type="button"
                      key={option.name + name}
                      style={{
                        border: selected
                          ? '1px solid black'
                          : '1px solid transparent',
                        opacity: available ? 1 : 0.3,
                      }}
                      disabled={!exists}
                      onClick={() => {
                        if (!selected) {
                          // Navigate to `?${variantUriQuery}`
                        }
                      }}
                    >
                      <ProductOptionSwatch swatch={swatch} name={name} />
                    </button>
                  );
                }
              })}
            </div>
            <br />
          </div>
        ))}
      </>
    );
  }

  function ProductOptionSwatch({
    swatch,
    name,
  }: {
    swatch?: Maybe<ProductOptionValueSwatch> | undefined;
    name: string;
  }) {
    const image = swatch?.image?.previewImage?.url;
    const color = swatch?.color;

    if (!image && !color) return name;

    return (
      <div
        aria-label={name}
        style={{
          backgroundColor: color || 'transparent',
        }}
      >
        {!!image && <img src={image} alt={name} />}
      </div>
    );
  }
  ```

## Related

[- mapSelectedProductOptionToObject](https://shopify.dev/api/hydrogen/utilities/mapselectedproductoptiontoobject)

[- getAdjacentAndFirstAvailableVariants](https://shopify.dev/api/hydrogen/utilities/getadjacentandfirstavailablevariants)

[- useSelectedOptionInUrlParam](https://shopify.dev/api/hydrogen/utilities/useselectedoptioninurlparam)
