Skip to main content

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.


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 options
options
<TVariant, <>>[]
required

The options array from the product form state.

TVariant extends | null

The matching variant, or null when the selection is partial or your query didn't load that variant.

Examples

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");
}

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 selectedOptions argument of your Storefront API product query, or as the starting selection of a product form store.

Anchor to input1
input1
{ searchParams: URLSearchParams; allowedOptionNames?: readonly string[]; }
required

The search params to read and an optional list of allowed option names. With allowedOptionNames, 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.

Examples

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 },
});
}

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 handleShopifyRoutes handler redirects variant links to option param URLs.

Anchor to input1
input1
{ style?: ; selectedOptions: readonly []; variant?: { id: string; }; optionNames: readonly string[]; base?: URLSearchParams; }
required

The selected options, the current product's option names, and an optional variant, link style, and base params.

URLSearchParams

New search params that hold the kept base params and the selection.

Examples

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);
}

Pass the names from product.options as optionNames in product links, and as allowedOptionNames after you've loaded the product.


Was this page helpful?