---
title: useOptimisticVariant
description: >-
  The useOptimisticVariant takes an existing product variant, processes a
  pending navigation to another product variant, and returns the data of the
  destination variant.
api_version: 2026-04
source_url:
  html: 'https://shopify.dev/docs/api/hydrogen/latest/hooks/useoptimisticvariant'
  md: 'https://shopify.dev/docs/api/hydrogen/latest/hooks/useoptimisticvariant.md'
api_name: hydrogen
---

# use​Optimistic​Variant

The `useOptimisticVariant` takes an existing product variant, processes a pending navigation to another product variant, and returns the data of the destination variant. This makes switching product options immediate.

## use​Optimistic​Variant(**[selectedVariant](#props-propertydetail-selectedvariant)**​,**[variants](#props-propertydetail-variants)**​)

### Parameters

* **selected​Variant**

  **SelectedVariant**

  **required**

  The `selectedVariant` field queried with `variantBySelectedOptions`.

* **variants**

  **Variants**

  **required**

  The available product variants for the product. This can be an array of variants, a promise that resolves to an array of variants, or an object with a `product` key that contains the variants.

### Returns

* **OptimisticVariant\<SelectedVariant = OptimisticVariantInput>**

  A new product object where the `selectedVariant` property is set to the variant that matches the current URL search params. If no variant is found, the original product object is returned. The `isOptimistic` property is set to `true` if the `selectedVariant` has been optimistically changed.

### OptimisticVariant

```ts
T & {
  isOptimistic?: boolean;
}
```

### OptimisticVariantInput

* \_\_typename

  ```ts
  'ProductVariant'
  ```

* availableForSale

  Indicates if the product variant is available for sale.

  ```ts
  boolean
  ```

* barcode

  The barcode (for example, ISBN, UPC, or GTIN) associated with the variant.

  ```ts
  Maybe<Scalars['String']['output']>
  ```

* compareAtPrice

  The compare at price of the variant. This can be used to mark a variant as on sale, when \`compareAtPrice\` is higher than \`price\`.

  ```ts
  Maybe<MoneyV2>
  ```

* compareAtPriceV2

  The compare at price of the variant. This can be used to mark a variant as on sale, when \`compareAtPriceV2\` is higher than \`priceV2\`.

  ```ts
  Maybe<MoneyV2>
  ```

* components

  List of bundles components included in the variant considering only fixed bundles.

  ```ts
  ProductVariantComponentConnection
  ```

* currentlyNotInStock

  Whether a product is out of stock but still available for purchase (used for backorders).

  ```ts
  boolean
  ```

* groupedBy

  List of bundles that include this variant considering only fixed bundles.

  ```ts
  ProductVariantConnection
  ```

* id

  A globally-unique ID.

  ```ts
  string
  ```

* image

  Image associated with the product variant. This field falls back to the product image if no image is available.

  ```ts
  Maybe<Image>
  ```

* metafield

  A \[custom field]\(https://shopify.dev/docs/apps/build/custom-data), including its \`namespace\` and \`key\`, that's associated with a Shopify resource for the purposes of adding and storing additional information.

  ```ts
  Maybe<Metafield>
  ```

* metafields

  A list of \[custom fields]\(/docs/apps/build/custom-data) that a merchant associates with a Shopify resource.

  ```ts
  Array<Maybe<Metafield>>
  ```

* price

  The product variant’s price.

  ```ts
  MoneyV2
  ```

* priceV2

  The product variant’s price.

  ```ts
  MoneyV2
  ```

* product

  The product object that the product variant belongs to.

  ```ts
  Product
  ```

* quantityAvailable

  The total sellable quantity of the variant for online sales channels.

  ```ts
  Maybe<Scalars['Int']['output']>
  ```

* quantityPriceBreaks

  A list of quantity breaks for the product variant.

  ```ts
  QuantityPriceBreakConnection
  ```

* quantityRule

  The quantity rule for the product variant in a given context.

  ```ts
  QuantityRule
  ```

* requiresComponents

  Whether a product variant requires components. The default value is \`false\`. If \`true\`, then the product variant can only be purchased as a parent bundle with components.

  ```ts
  boolean
  ```

* requiresShipping

  Whether a customer needs to provide a shipping address when placing an order for the product variant.

  ```ts
  boolean
  ```

* selectedOptions

  List of product options applied to the variant.

  ```ts
  Array<SelectedOption>
  ```

* sellingPlanAllocations

  Represents an association between a variant and a selling plan. Selling plan allocations describe which selling plans are available for each variant, and what their impact is on pricing.

  ```ts
  SellingPlanAllocationConnection
  ```

* shopPayInstallmentsPricing

  The Shop Pay Installments pricing information for the product variant.

  ```ts
  Maybe<ShopPayInstallmentsProductVariantPricing>
  ```

* sku

  The SKU (stock keeping unit) associated with the variant.

  ```ts
  Maybe<Scalars['String']['output']>
  ```

* storeAvailability

  The in-store pickup availability of this variant by location.

  ```ts
  StoreAvailabilityConnection
  ```

* taxable

  Whether tax is charged when the product variant is sold.

  ```ts
  boolean
  ```

* title

  The product variant’s title.

  ```ts
  string
  ```

* unitPrice

  The unit price value for the variant based on the variant's measurement.

  ```ts
  Maybe<MoneyV2>
  ```

* unitPriceMeasurement

  The unit price measurement for the variant.

  ```ts
  Maybe<UnitPriceMeasurement>
  ```

* weight

  The weight of the product variant in the unit system specified with \`weight\_unit\`.

  ```ts
  Maybe<Scalars['Float']['output']>
  ```

* weightUnit

  Unit of measurement for weight.

  ```ts
  WeightUnit
  ```

### MoneyV2

Supports MoneyV2 from both Storefront API and Customer Account API. The APIs may have different CurrencyCode enums (e.g., Customer Account API added USDC in 2025-10, but Storefront API doesn't support USDC in 2025-10). This union type ensures Money component works with data from either API.

```ts
StorefrontApiMoneyV2 | CustomerAccountApiMoneyV2
```

Examples

### Examples

* #### Example code

  ##### JavaScript

  ```jsx
  import {useLoaderData} from 'react-router';
  import {useOptimisticVariant} from '@shopify/hydrogen';

  export async function loader({context}) {
    return {
      product: await context.storefront.query('/** product query **/'),
      // Note that variants does not need to be awaited to be used by `useOptimisticVariant`
      variants: context.storefront.query('/** variants query **/'),
    };
  }

  function Product() {
    const {product, variants} = useLoaderData();

    // The selectedVariant optimistically changes during page
    // transitions with one of the preloaded product variants
    const selectedVariant = useOptimisticVariant(
      product.selectedVariant,
      variants,
    );

    // @ts-ignore
    return <ProductMain selectedVariant={selectedVariant} />;
  }
  ```

  ##### TypeScript

  ```tsx
  import {useLoaderData} from 'react-router';
  import {LoaderFunctionArgs} from 'react-router';
  import {useOptimisticVariant} from '@shopify/hydrogen';

  export async function loader({context}: LoaderFunctionArgs) {
    return {
      product: await context.storefront.query('/** product query */'),
      // Note that variants does not need to be awaited to be used by `useOptimisticVariant`
      variants: context.storefront.query('/** variants query */'),
    };
  }

  function Product() {
    const {product, variants} = useLoaderData<typeof loader>();

    // The selectedVariant optimistically changes during page
    // transitions with one of the preloaded product variants
    const selectedVariant = useOptimisticVariant(
      product.selectedVariant,
      variants,
    );

    // @ts-ignore
    return <ProductMain selectedVariant={selectedVariant} />;
  }
  ```

***

## Related

[VariantSelector](https://shopify.dev/docs/api/hydrogen/2026-04/components/variantselector)

[useOptimisticCart](https://shopify.dev/docs/api/hydrogen/2026-04/hooks/useoptimisticcart)

***
