variant
The variant object is one purchasable combination of a product’s option
values. It carries the effective price, inventory state, media, quantity rules,
pickup availability, and the Sellerlane product-kind capabilities inherited
from its parent product.
Availability and context
Variants are most commonly returned by product.variants,
product.selected_variant, product.first_available_variant, and
product.selected_or_first_available_variant. They also appear on cart and
order resources. variant.product can be nil when the parent cannot be
resolved in the current storefront, so guard it when the surrounding context
does not already provide a product.
Examples
Render the selected option values
Prefer selected_options or option_values over the legacy option1,
option2, and option3 aliases.
{% assign variant = product.selected_or_first_available_variant %}
{% if variant %} <h2>{{ variant.title | escape }}</h2> <dl> {% for selected_option in variant.selected_options %} <dt>{{ selected_option.name | escape }}</dt> <dd>{{ selected_option.value | escape }}</dd> {% endfor %} </dl>{% endif %}Example output:
<h2>Red / Medium</h2><dl> <dt>Color</dt><dd>Red</dd> <dt>Size</dt><dd>Medium</dd></dl>Show price and inventory-safe availability
Use available to decide whether the buyer can purchase. It accounts for the
product kind, the catalog-level purchasable flag, inventory tracking, stock,
and the backorder policy.
{% if variant.available %} <span>{{ variant.price | money }}</span> {% if variant.on_sale %} <s>{{ variant.compare_at_price | money }}</s> {% endif %}{% else %} <span>Sold out</span>{% endif %}Example output:
<span>₹1,499.00</span><s>₹1,799.00</s>Do not use inventory_quantity > 0 as the purchase test. Untracked inventory,
backorders, and non-inventory product kinds can be available with a zero
quantity.
Highlight variants matched by active filters
{% for variant in product.variants %} <a href="{{ variant.url }}" {% if variant.selected %}aria-current="true"{% endif %} {% unless variant.matched %}hidden{% endunless %}> {{ variant.option_values_concatenated | escape }} </a>{% endfor %}Example output for a blue-color filter:
<a href="/products/linen-shirt?variant=var_blue_small">Blue / Small</a><a href="/products/linen-shirt?variant=var_blue_medium" aria-current="true">Blue / Medium</a>Without an active variant filter, every variant has matched == true.
Respect quantity rules and pickup availability
<input type="number" name="quantity" min="{{ variant.quantity_rule.min }}" {% if variant.quantity_rule.max %}max="{{ variant.quantity_rule.max }}"{% endif %} step="{{ variant.quantity_rule.increment }}" value="{{ variant.quantity_rule.min }}">
{% if variant.store_availabilities != empty %} <p>Pickup is available at {{ variant.store_availabilities.size }} location(s).</p>{% endif %}Example output:
<input type="number" name="quantity" min="2" max="20" step="1" value="2"><p>Pickup is available at 3 location(s).</p>store_availabilities is defined for the URL-selected variant and for the
product’s first available variant. These can be different variants, in which
case both can expose pickup rows. The array contains at most 250 active,
pickup-enabled, non-fulfillment locations in the store’s country, ordered with
the default location first and then by creation order.
Nil values and behavioral details
selectedis true only for the variant chosen by the URL or relevant-result context. It is not inferred from a theme loop.incomingapplies to inventory-capable product kinds when the storefront variant payload reports an incoming shipment; it does not additionally testinventory_tracked.next_incoming_dateisnilunlessincomingis true.weightis authoritative grams and can benil;gramsis the compatibility alias and is0when no shippable weight exists.weight_in_unitandweight_unitcan also benil.quantity_price_breaksis ordered by minimum quantity. The default quantity increment is1.purchasableis the catalog flag.purchase_readyadditionally requires a direct digital sale to declaredownload,license_key, orbothdelivery;availablethen applies the product-kind inventory rules.- Prices and store-credit-like amounts are currency minor units. Apply
moneywhen displaying them.
Variant drops expose buyer-safe storefront fields only. They do not reveal seller inventory internals, unpublished pickup locations, or raw database records through either property access or
| json.
Properties
| Property | Description |
|---|---|
variant.available | true when this variant is currently purchasable after product-kind and inventory rules. |
variant.backorder_allowed | true when inventory policy permits selling after stock reaches zero. |
variant.barcode | Barcode value. |
variant.bpn | Buyer-facing part number, or an empty string. |
variant.bulk_pricing_discount_type | Discount calculation type used by bulk-pricing tiers. |
variant.bulk_pricing_enabled | true when one or more bulk-pricing tiers apply. |
variant.bulk_pricing_tiers | Quantity tiers ordered by minimum quantity. |
variant.bundle | Variant-level bundle configuration, or nil. |
variant.bundle_items | Resolved items in the variant-level bundle. |
variant.compare_at_price | Original price before discount, if any. |
variant.compare_at_price_in_cents | Raw compare-at price in currency minor units, or nil. |
variant.created_at | Creation timestamp. |
variant.digital_delivery | Variant-level digital-delivery configuration, or nil. |
variant.featured_image | The featured image. |
variant.featured_media | The featured media item. |
variant.grams | Weight in whole grams; returns 0 when no shippable weight is defined. |
variant.gtin | Global Trade Item Number, or an empty string. |
variant.has_price | true when the variant has a finite effective price. |
variant.has_price? | Boolean alias of has_price. |
variant.id | Unique identifier. |
variant.image | Primary image. |
variant.image_url | Direct URL of the primary variant image, or an empty string. |
variant.images | All images. |
variant.incoming | true for an inventory-capable product kind when the storefront variant payload reports an incoming shipment; it does not additionally test inventory_tracked. |
variant.inventory_management | Inventory tracking system, if any. |
variant.inventory_policy | ’deny’ or ‘continue’ — selling when out of stock. |
variant.inventory_quantity | Units in stock. |
variant.inventory_tracked | true when this product kind and variant use tracked inventory. |
variant.matched | true for all variants without a variant filter; otherwise true only for variants matching the active filters. |
variant.media | All media (images, video, 3D). |
variant.metafields | Metafields on this resource. |
variant.mpn | Manufacturer Part Number, or an empty string. |
variant.msrp | Manufacturer suggested retail price in currency minor units, or nil. |
variant.name | Name. |
variant.next_incoming_date | Earliest active incoming shipment date, or nil when inventory is not incoming. |
variant.on_sale | true when the effective price is below the compare-at price. |
variant.option_1 | Compatibility alias of option1. |
variant.option_2 | Compatibility alias of option2. |
variant.option_3 | Compatibility alias of option3. |
variant.option_names | Selected option names in position order. |
variant.option_values | Selected option values in position order. |
variant.option_values_by_name | Selected option values keyed by their option name. |
variant.option_values_concatenated | Selected option values joined with /. |
variant.option1 | First selected option value, or an empty string. |
variant.option2 | Second selected option value, or an empty string. |
variant.option3 | Third selected option value, or an empty string. |
variant.options | Selected option-value objects in position order. |
variant.price | Effective price in currency minor units, or nil when neither a base nor sale price is configured. Format with money. |
variant.price_in_cents | Configured base price in currency minor units, or nil. |
variant.price_unavailable | true when this variant had its prices withheld after a failed catalog price resolution; renders as price-unavailable, never as sold out. |
variant.price_unavailable? | Boolean alias of price_unavailable. |
variant.product | Parent product, loaded in the current store, or nil. |
variant.product_id | Parent product identifier. |
variant.product_type | Sellerlane product kind inherited from the parent product. |
variant.public_title | Variant title without the platform default-title placeholder. |
variant.purchasable | Catalog-level purchasable flag before inventory availability is applied. |
variant.purchase_ready | true when the variant is catalog-purchasable and any direct digital sale declares a supported delivery mode; inventory is still checked separately by available. |
variant.purchase_ready? | Boolean alias of purchase_ready. |
variant.quantity_price_breaks | Ordered quantity price breaks for the variant. |
variant.quantity_price_breaks_configured | true when quantity_price_breaks is non-empty. |
variant.quantity_price_breaks_configured? | Boolean alias of quantity_price_breaks_configured. |
variant.quantity_rule | The variant quantity rule. |
variant.regular_price | Non-sale unit price in currency minor units, or nil. |
variant.requires_selling_plan | Always false because selling plans are unavailable. |
variant.requires_shipping | true when physical delivery is needed. |
variant.sale_price_in_cents | Configured sale price in currency minor units, or nil. |
variant.selected | true when this variant is selected by the current URL or relevant-result context. |
variant.selected_options | Selected name/value option objects in position order. |
variant.selected_selling_plan_allocation | Always nil because selling plans are unavailable. |
variant.selected? | Boolean alias of selected. |
variant.selling_plan_allocations | Always empty because selling plans are unavailable. |
variant.sku | Stock keeping unit. |
variant.store_availabilities | Up to 250 pickup-availability rows for the URL-selected variant and the product’s first available variant; empty in other variant contexts. |
variant.taxable | true when taxed. |
variant.title | Display title. |
variant.unit_price | Unit price in currency minor units, or nil when not configured. |
variant.unit_price_measurement | Measurement basis used with unit_price, or nil. |
variant.upc | Universal Product Code, or an empty string. |
variant.updated_at | Last update timestamp. |
variant.url | Relative URL of the resource. |
variant.videos | Video and external-video media attached to the variant. |
variant.weight | Weight in grams, or nil when the product kind is not shippable or no authoritative weight can be resolved. |
variant.weight_in_unit | Merchant-entered weight expressed in weight_unit, or nil when the variant has no weight. |
variant.weight_unit | Unit for weight display. |
Property names are generated from the storefront engine (VariantDrop), so the
list matches what themes can access. {{ variant | json }} is a curated
synchronous snapshot: it omits some public properties, always serializes
store_availabilities as an empty array, and removes inventory quantity and
policy. Inspect those properties directly when needed.
Sellerlane differences from Shopify
- Selling plans are not supported.
requires_selling_planisfalse,selected_selling_plan_allocationisnil, andselling_plan_allocationsis empty. - Quantity price breaks come from Sellerlane bulk-pricing tiers; they are not Shopify B2B price lists or company-location pricing.
product_typecan bephysical,digital,gift_card,event, orbundle. These native types determine whether shipping and inventory concepts apply.option1,option2,option3, and their underscore aliases remain for theme compatibility, but new themes should useselected_options,option_values, oroption_values_by_name.