get Product Optionsutility
utility
Returns a product options array with its relevant information about the variant. This function supports combined listing products and products with 2000 variants limit.
Was this section helpful?
Example code
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>
);
}