Variant selection
The variant selection functions read the customer's option selection and turn the selection into product links. Use these functions to read selected options from the request URL, get the selected variant from the product form, and build product links for a selection.
Import getSelectedProductOptions, getSelectedVariant, and buildProductSelectionSearchParams from @shopify/hydrogen.
Anchor to Selected variantSelected variant
Returns the variant that matches the customer's current option selection.
Show the product's price range until the selection resolves to a variant. When every option has a selection and the function returns null, query the exact variant from the Storefront API.
Anchor to getSelectedVariant-parametersParameters
- Anchor to optionsoptionsoptionsVariantOptionState<TVariant, ProductOptionValueInput<ProductVariantInput>>[]VariantOptionState<TVariant, ProductOptionValueInput<ProductVariantInput>>[]requiredrequired
The
optionsarray from the product form state.
The matching variant, or
nullwhen the selection is partial or your query didn't load that variant.
VariantOptionState
State of one product option, such as "Color", and its values.
- name
Option name, such as "Color".
string - values
State of each value, in the product's value order.
VariantOptionValueState<TVariant, TOptionValue>[]
VariantOptionValueState
State of one option value, such as "Red" under "Color", for the current selection. Render the value's control and link from this state.
- available
Whether the variant for the targeted selection is available for sale. Without the encoded variant availability in your query, the value comes from the loaded variant, or reads `false` when your query didn't load that variant.
boolean - exists
Whether a variant exists for the selection that the value targets. Defaults to `true` when your query doesn't select the encoded variant existence field.
boolean - handle
Product handle for the option link. A value from another product in a combined listing uses that product's handle. Selected values use the current product's handle.
string - name
Option value name, such as "Red".
string - selected
Whether the customer has selected the value.
boolean - selectedOptions
Selection that the value targets. Build the option link from this selection. Selecting the value can produce a different selection.
SelectedOption[] - swatch
Swatch data from the option value in your query.
TOptionValue["swatch"] - variant
Variant for the targeted selection, or `null` when the selection is partial or your query didn't load that variant.
TVariant | null
SelectedOption
A single selected product option, such as `{ name: "Color", value: "Red" }`.
- name
Option name, such as "Color".
string - value
Value chosen for the option, such as "Red".
string
ProductOptionValueInput
A single option value, such as "Small" or "Red", within a product option.
- firstSelectableVariant
Variant that combines this value with the lowest-position values of every other option. Include this field in your query. The store uses the variant to resolve option values and to find values that belong to other products in a combined listing.
TVariant | null - name
Option value name, such as "Small" or "Red".
string - swatch
Swatch data from your query. The option value state returns the swatch unchanged.
unknown
ProductVariantInput
Variant fields that the product form needs from your Storefront API query. Pass your full query type, which can include more fields.
- availableForSale
Whether the customer can buy the variant. Option value availability falls back to this field when your query doesn't select the encoded variant availability.
boolean - compareAtPrice
Compare-at price, or `null` when the variant has none.
Money | null - id
Variant ID that the product form adds to the cart.
string - image
Variant image. The cart shows the image on an added line before the server responds.
unknown - price
Variant price. The cart shows the price on an added line before the server responds.
Money - product
Handle and title of the variant's product. A handle that differs from the current product marks a variant of another product in a combined listing.
{ handle: string; title?: string | null } | null - selectedOptions
Option names and values that make up the variant.
SelectedOption[] - sku
Variant SKU.
string | null - title
Variant title. The cart shows the title on an added line before the server responds.
string
Money
A monetary value from the Storefront API.
- amount
The decimal amount as a string, such as `29.99`.
string - currencyCode
The ISO 4217 currency code, such as `USD`.
string
TypeScript
Examples
Description
Read the selected variant from the current product form store state.
TypeScript
import { getSelectedVariant, type ProductFormStore } from "@shopify/hydrogen"; declare const store: ProductFormStore; const variant = getSelectedVariant(store.getState().options); if (variant) { console.log(variant.id, variant.price.amount, variant.price.currencyCode); } else { console.log("Select options"); }
Anchor to Selected optionsSelected options
Reads the customer's option selection from a product URL's search params.
Each param becomes an option name and value. For example, ?Color=Red&Size=M becomes Color set to Red and Size set to M. The function always skips the variant param, which holds a numeric variant ID in Liquid storefront URLs.
Pass the result as the argument of your Storefront API product query, or as the starting selection of a product form store.
- Anchor to input1input1input1{ searchParams: URLSearchParams; allowedOptionNames?: readonly string[]; }{ searchParams: URLSearchParams; allowedOptionNames?: readonly string[]; }requiredrequired
The search params to read and an optional list of allowed option names. With
, the function keeps only params whose name exactly matches an allowed name, and an empty list keeps no params. Pass the product's option names to keep unrelated params out of the selection.
The selected options, in the order that they appear in the URL.
TypeScript
Examples
Description
Read option parameters, such as `?Color=Red&Size=M`, from the request URL and pass the selection to a Storefront API product query.
TypeScript
import { getSelectedProductOptions } from "@shopify/hydrogen"; declare const storefrontClient: { graphql(query: string, options: { variables: Record<string, unknown> }): Promise<unknown>; }; declare const PRODUCT_QUERY: string; export async function loader({ request, params }: { request: Request; params: { handle: string } }) { const selectedOptions = getSelectedProductOptions({ searchParams: new URL(request.url).searchParams, }); return storefrontClient.graphql(PRODUCT_QUERY, { variables: { handle: params.handle, selectedOptions }, }); }Description
Keep only parameters that match the product's option names. This example drops the `ref` and `variant` parameters.
TypeScript
import { getSelectedProductOptions, type ProductInput } from "@shopify/hydrogen"; declare const product: ProductInput; const searchParams = new URLSearchParams("Color=Red&Size=M&ref=campaign&variant=123"); const selectedOptions = getSelectedProductOptions({ searchParams, allowedOptionNames: product.options.map((option) => option.name), });
Anchor to Product linksProduct links
Builds the search params for a product URL that holds the customer's variant selection.
The function keeps unrelated params from the base params, such as ?ref=campaign, and replaces any earlier selection. Pass the current product's option names to clear the current product's params when you link to another product in a combined listing.
The default options style writes one param per option. The variant style writes a single numeric variant ID param for shareable links. The variant style falls back to option params when you pass no variant or when the variant ID isn't a numeric product variant GID. The handler redirects variant links to option param URLs.
- Anchor to input1input1input1{ style?: ProductSelectionLinkStyle; selectedOptions: readonly SelectedOption[]; variant?: { id: string; }; optionNames: readonly string[]; base?: URLSearchParams; }{ style?: ProductSelectionLinkStyle; selectedOptions: readonly SelectedOption[]; variant?: { id: string; }; optionNames: readonly string[]; base?: URLSearchParams; }requiredrequired
The selected options, the current product's option names, and an optional variant, link style, and base params.
New search params that hold the kept base params and the selection.
ProductSelectionLinkStyle
How a product URL encodes the customer's variant selection. - `options`: one param per option, such as `?Color=Red&Size=M`. - `variant`: a single `?variant=<numeric id>` param that matches Liquid storefront URLs.
"options" | "variant"TypeScript
Examples
Description
If the selection is valid, then build a product URL from the selected options in the result. If the selection matches a variant that your query loaded, then replace the current URL with the product URL. Otherwise, load the product URL. The product URL keeps unrelated parameters from the current URL.
TypeScript
import { buildProductSelectionSearchParams, type ProductFormStore } from "@shopify/hydrogen"; declare const store: ProductFormStore; declare const product: { handle: string; options: Array<{ name: string }> }; const result = store.selectOption("Color", "Red"); if (result.status !== "invalid") { const searchParams = buildProductSelectionSearchParams({ selectedOptions: result.selectedOptions, optionNames: product.options.map((option) => option.name), base: new URLSearchParams(location.search), }); const url = `/products/${product.handle}${searchParams.size ? `?${searchParams}` : ""}`; if (result.status === "resolved") history.replaceState(history.state, "", url); else location.replace(url); }
Anchor to Option namesOption names
Pass the names from product.options as optionNames in product links, and as allowedOptionNames after you've loaded the product.