# getProductOptions Returns a product options array with its relevant information about the variant. This function supports combined listing products and products with 2000 variants limit. ```jsx import React from 'react'; import {getProductOptions} from '@shopify/hydrogen-react'; // 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) => (
{option.name}
{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 ( ); } 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 ( ); } })}

))} ); } function ProductOptionSwatch({swatch, name}) { const image = swatch?.image?.previewImage?.url; const color = swatch?.color; if (!image && !color) return name; return (
{!!image && {name}}
); } ``` ```tsx import React from 'react'; import { getProductOptions, type MappedProductOptions, } from '@shopify/hydrogen-react'; import type { ProductOptionValueSwatch, Maybe, } from '@shopify/hydrogen-react/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) => (
{option.name}
{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 ( ); } 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 ( ); } })}

))} ); } function ProductOptionSwatch({ swatch, name, }: { swatch?: Maybe | undefined; name: string; }) { const image = swatch?.image?.previewImage?.url; const color = swatch?.color; if (!image && !color) return name; return (
{!!image && {name}}
); } ```