---
title: Support product variants
description: Learn how to support product variants in your theme.
source_url:
  html: 'https://shopify.dev/docs/storefronts/themes/product-merchandising/variants'
  md: >-
    https://shopify.dev/docs/storefronts/themes/product-merchandising/variants.md
api_name: liquid
---

# Support product variants

Products can be broken up into a maximum of three options, and a single combination of those options is a variant. For example, if a t-shirt comes in sizes `S`, `M`, and `L`, and colors `Black`, `White`, and `Red`, then `S/Black` would be a variant of that product.

In this tutorial, you'll learn how to support product variants in your theme.

***

## Resources

To support product variants, you'll use the following:

* The [`product` object](https://shopify.dev/docs/api/liquid/objects/product)
* The [`variant` object](https://shopify.dev/docs/api/liquid/objects/variant)

***

## Implementing product variants

To support variants in your theme, you need to implement the following components:

* [Variant deep link handling](#variant-deep-link-handling): A variant can be linked to directly, so you should ensure that the product information is updated for the "selected" variant when a variant is referenced in a product link.

* [Variant selectors](#variant-selectors): You should build a variant selector to allow customers to easily browse the available variants of a product. Selecting a variant should update the page with variant-specific information.

  You might want to add these components to a section that can be included in a JSON product template, or a Liquid product template.

***

## Variant deep link handling

Variant deep links are product links that contain a `?variant=[variant-id]` query parameter, where `[variant-id]` is the [ID](https://shopify.dev/docs/api/liquid/objects/variant#variant-id) of the associated variant. This allows you to link directly to a variant. You can add this functionality to a section that can be included in a JSON product template, or a Liquid product template.

When variants are deep-linked, you can access which variant is linked through the `selected_variant` attribute of the [`product` object](https://shopify.dev/docs/api/liquid/objects/product#product-selected_variant). However, a product link won't always contain a deep-linked variant. In these cases, you can default to the selected, first available, or first variant through the `selected_or_first_available_variant` attribute.

You can also deep link using the format `?option_values=[option-value-id-1],...,[option-value-id-N]` where `[option-value-id]` is the [ID](https://shopify.dev/docs/api/liquid/objects/product_option_value#product_option_value-id) of the associated option value. One option value ID must be provided per product option and the order must match the option order. If the option value combination maps to a variant that is not present, the requested option values will be selected but the product fields [`selected_variant`](https://shopify.dev/docs/api/liquid/objects/product#product-selected_variant) and [`selected_or_first_available_variant`](https://shopify.dev/docs/api/liquid/objects/product#product-selected_or_first_available_variant) will return null.

After you identify the variant that you want to display, you need to ensure that the following product elements reflect it:

* Product media
* Product price
* Variant selector

### Example

The following example assigns a default variant using `product.selected_or_first_available_variant`, populates a basic media and price display based on that variant, and selects that variant in a basic variant selector.

```liquid
{% assign current_variant = product.selected_or_first_available_variant %}


<!-- Product media -->
{% assign featured_media = current_variant.featured_media %}


{% case featured_media.media_type %}
{% when 'image' %}
  <div className="product-single__media"
    style={{paddingTop: '{{ 1 | divided_by'}}
    data-media-id="{{ featured_media.id }}"
  >
    {{ featured_media | image_url: width: 2048 | image_tag }}
  </div>
{% when 'external_video' %}
  <div className="product-single__media"
    style={{paddingTop: '{{ 1 | divided_by'}}
    data-media-id="{{ featured_media.id }}"
  >
    {{ featured_media | external_video_tag }}
  </div>
{% when 'video' %}
  <div className="product-single__media" data-media-id="{{ featured_media.id }}">
    {{ featured_media | video_tag: controls: true }}
  </div>
{% when 'model' %}
  <div className="product-single__media"
    style={{paddingTop: '100%'}}
    data-media-id="{{ featured_media.id }}"
  >
    {{ featured_media | model_viewer_tag }}
  </div>
{% else %}
  <div className="product-single__media"
    style={{paddingTop: '100%'}}
    data-media-id="{{ featured_media.id }}"
  >
    {{ featured_media | media_tag }}
  </div>
{% endcase %}


<!-- Product price -->
<div className="price">
<span className="price-reg">{{ current_variant.price | money }}</span>


{% if current_variant.compare_at_price > current_variant.price %}
  <span className="price-sale"><s>{{ current_variant.compare_at_price | money }}</s></span>
{% endif %}
</div>


<!-- Variant selector -->
<select name="id">
{% for variant in product.variants %}
  <option value="{{ variant.id }}"
    {% if variant == current_variant %}selected="selected"{% endif %}
  >
    {{ variant.title }} - {{ variant.price | money }}
  </option>
{% endfor %}
</select>
```

***

## Variant selectors

You can use a single variant selector where each option represents a variant. However, products may have more than one option. For a better buyer experience and to avoid future compatibility issues, we recommend that you present each of these options separately in the UI. To achieve this, you can use the [`product.options_with_values` object](https://shopify.dev/docs/api/liquid/objects/product#product-options_with_values) to generate a selector for each option. You can then use JavaScript to update the state when a new option value is selected.

**Note:**

Regardless of the approach you use for variant selection, you need to ensure that when a new variant is selected, the product media and price are updated to reflect the selected variant.

Variant selectors should be added to a section that can be included in a JSON product template, or a Liquid product template. They can also be included in product grid or product quick view snippets to allow customers to view variants on other pages, like collections.

**Tip:**

Refer to the following files in Dawn for an example implementation:

* [`product-variant-picker.liquid` section](https://github.com/Shopify/dawn/blob/main/snippets/product-variant-picker.liquid)
* [`global.js` asset](https://github.com/Shopify/dawn/blob/main/assets/global.js)

***
