Skip to main content


The useProductOptions hook returns an object that enables you to keep track of the selected variant and/or selling plan state, as well as callbacks for modifying the state. The useProductOptions hook must be a child of the ProductOptionsProvider component.

Example code

* Iterate through a list of variants and allow the customer to select a specific variant.
import {useProductOptions} from '@shopify/hydrogen';

export function MyComponent() {
const {variants, selectedVariant, setSelectedVariant} = useProductOptions();

return (
<label htmlFor="variants">Select a variant</label>
onChange={(e) =>
variants.find((variant) => ===
{ => (
<option key={} value={}>
* Support selling plans. You should display a selling plan selector to a user
* when a product has selling plans enabled. You need to pass `sellingPlanGroups` to the hook.
import {useProductOptions} from '@shopify/hydrogen';

export function MyComponent() {
const {
} = useProductOptions({
variants: product.variants,
sellingPlanGroups: product.sellingPlanGroups,
initialVariantId: product.variants.edges[0],

return (
{/* Code for your variant selector goes here */}

{ => (
<div key={}>
{ => {
return (
<li key={}>
<button onClick={() => setSelectedSellingPlan(sellingPlan)}>
* Use product options.
import {useProductOptions} from '@shopify/hydrogen';

export function MyComponent() {
const {options, selectedVariant, selectedOptions, setSelectedOption} =
useProductOptions({variants: product.variants});

return (
{{name, values}) => (
<fieldset key={name}>
{ => (
<label htmlFor={`option[${name}][${value}]`}>
checked={selectedOptions[name] === value}
onChange={() => setSelectedOption(name, value)}


  • To make sure you have all the data necessary for the useProductOptions hook, refer to the Storefront API's ProductVariant object.
  • If your product requires a selling plan, then make sure to display that as required in your user interface. If it doesn't require a selling plan, then you might want to offer a "one-time purchase" option which triggers setSelectedSellingPlan(null).
  • You can use selectedSellingPlanAllocation to display the price adjustments for the selected variant when a given selling plan is active.
  • You can manually deselect a variant by calling setSelectedVariant(null).


This hook takes a single object with the following keys:

variants?PartialDeep&#60;ProductVariantConnection&#62;The product's VariantConnection.
sellingPlanGroups?PartialDeep&#60;SellingPlanGroupConnection&#62;The product's SellingPlanGroups.
initialVariantId?ProductVariantType['id']The initially selected variant.

Return value

This hook returns a single object with the following keys:

variantsAn array of the variant nodes from the VariantConnection.
optionsAn array of the product's options and values.
selectedVariantThe selected variant.
setSelectedVariantA callback to set the selected variant to the variant passed as an argument.
selectedOptionsThe current selected options.
setSelectedOptionA callback to set the selected option.
setSelectedOptionsA callback to set multiple selected options at once.
isOptionInStockA callback that returns a boolean indicating if the option is in stock.
setSelectedSellingPlanA callback to set the selected selling plan to the one passed as an argument.
selectedSellingPlanThe selected selling plan.
selectedSellingPlanAllocationThe selected selling plan allocation.
sellingPlanGroupsThe selling plan groups.


The Product object includes variables that you will need to provide values for when performing your query.

$numProductVariantMetafieldsThe number of Metafield objects to query for in a variant's MetafieldConnection.
$numProductVariantSellingPlanAllocationsThe number of SellingPlanAllocations to query for in a variant's SellingPlanAllocationConnection.
$numProductSellingPlanGroupsThe number of SellingPlanGroups objects to query for in a SellingPlanGroupConnection.
$$numProductSellingPlansThe number of SellingPlan objects to query for in a SellingPlanConnection.