product
The product object represents a storefront product, including its pricing,
variants, options, media, tags, merchandising state, and Sellerlane product-type
capabilities.
Availability and context
On a product template, product is the product being viewed. A product object
can also be returned by collection.products, search results, all_products,
resource settings, and relationships such as a line item. Test the object before
using it when the surrounding resource is optional.
The object is storefront-scoped: unpublished products and collections are not made visible merely because a theme asks for them. Product URLs are localized for the active storefront locale.
Examples
Render a product card
{% if product %} <article> <a href="{{ product.url }}">{{ product.title | escape }}</a> <span>{{ product.price | money }}</span> {% unless product.available %}<span>Sold out</span>{% endunless %} </article>{% endif %}Example output:
<article> <a href="/products/sandalwood-soy-candle">Sandalwood Soy Candle</a> <span>₹1,499.00</span></article>Choose the selected or best fallback variant
Use selected_or_first_available_variant for an add-to-cart form. A valid
selected variant wins even when it is unavailable. With no valid selection,
Sellerlane chooses the first available variant, then the first variant when the
product is completely unavailable.
{% assign current_variant = product.selected_or_first_available_variant %}
{% if current_variant %} <input type="hidden" name="id" value="{{ current_variant.id }}"> <p>{{ current_variant.title | escape }} — {{ current_variant.price | money }}</p>{% else %} <p>This product has no variants.</p>{% endif %}Example output:
<input type="hidden" name="id" value="var_01J8CANDLELARGE"><p>Large — ₹1,899.00</p>selected_variant is stricter: it is nil unless the current URL or relevant
result context identifies an existing variant. first_available_variant is
nil when no variant can currently be purchased.
Keep filtered results variant-aware
On a filtered collection or search page, a product can carry a relevant-variant
context. Its URL points at that variant, its featured media prefers that
variant’s media, and each variant exposes variant.matched.
<a href="{{ product.url }}"> {% if product.featured_image %} {{ product.featured_image | image_url: width: 640 | image_tag: alt: product.title }} {% endif %} {{ product.title | escape }}</a>
{% for variant in product.variants %} {% if variant.matched %} <span>{{ variant.title | escape }}</span> {% endif %}{% endfor %}Example output for a red-color filter:
<a href="/products/linen-shirt?variant=var_red_medium"> <img src="https://cdn.example.com/linen-red.jpg?width=640" alt="Linen Shirt"> Linen Shirt</a><span>Red / Medium</span>List tags and paginate variants
{% if product.tags != empty %} <ul> {% for tag in product.tags %}<li>{{ tag | escape }}</li>{% endfor %} </ul>{% endif %}
{% paginate product.variants by 50 %} {% for variant in product.variants %} <p>{{ variant.title | escape }} — {{ variant.price | money }}</p> {% endfor %} {{ paginate | default_pagination }}{% endpaginate %}Example output begins:
<ul><li>Candle</li><li>Gift</li><li>Home</li></ul><p>100 g — ₹1,499.00</p><p>200 g — ₹1,899.00</p>Nil values, ordering, and limits
product.variantsfollows seller-definedsort_orderand exposes at most 250 variants. Pagination supports a page size of up to 250.product.variants_countreports the full storefront variant count even when the exposed array is capped.product.tagsis alphabetically ordered and is empty when the product has no tags.product.template_suffix, variant-selection properties, optional media, and product-type configuration objects can benil.product.collectionscontains only published storefront collections.- Prices are integer currency minor units. Format them with
moneyor a related money filter instead of printing the raw number.
Product drops expose an audited storefront projection, not database records or seller-only fields.
{{ product | json }}returns a curated synchronous snapshot, not every property listed below. In particular, lazy properties must be read directly, and the serialized embedded-variant list is not theproduct.variantsLiquid collection with its 250-item cap.
Properties
| Property | Description |
|---|---|
product.available | true when the product is published, its purchase mode allows normal purchasing, and at least one variant passes its inventory availability rules. A pending preorder uses preorderable instead. |
product.available_now | true when the product is published and its purchase mode is available_now, or when a dated preorder has been released. This does not test inventory. |
product.available_now? | Boolean alias of available_now. |
product.backorder_allowed | Backorder policy of the merchandising variant. |
product.barcode | Barcode value. |
product.booking | Event booking configuration, or nil for a non-event product. |
product.brand_name | Merchant-facing vendor or brand name. |
product.bulk_pricing_discount_type | Discount calculation type used by the active bulk-pricing tiers. |
product.bulk_pricing_enabled | true when at least one bulk-pricing tier applies. |
product.bulk_pricing_tiers | Quantity tiers ordered by their minimum quantity. |
product.bundle | Bundle configuration for a bundle product, or nil. |
product.bundle_items | Resolved items in the active bundle configuration. |
product.bundle? | true for a Sellerlane bundle product. |
product.category | Resolved product taxonomy category, or nil. |
product.category_id | Stored taxonomy category identifier. |
product.category_name | Merchant-facing taxonomy category name. |
product.collections | Published storefront collections containing this product. |
product.compare_at_price | Lowest effective compare-at price among purchasable variants, or nil; falls back to denormalized product pricing when no purchasable variant has a finite price. |
product.compare_at_price_max | Highest effective compare-at price among purchasable variants, or nil; falls back to denormalized product pricing when necessary. |
product.compare_at_price_min | Lowest effective compare-at price among purchasable variants, or nil; falls back to denormalized product pricing when necessary. |
product.compare_at_price_varies | true when the effective compare-at price differs across the purchasable-variant price projection. |
product.contact_purchase | true when the buyer must contact the seller instead of adding the product to cart. |
product.contact_purchase_message | Seller-authored instructions for a contact-to-purchase product. |
product.contact_purchase? | Boolean alias of contact_purchase. |
product.content | Body content (HTML). |
product.created_at | Creation timestamp. |
product.customs | Customs and harmonized-code information, or nil when it does not apply. |
product.customs_info | Alias of customs. |
product.description | Description (HTML). |
product.digital_delivery | Digital-delivery configuration, or nil for a non-digital product. |
product.digital? | true for a Sellerlane digital product. |
product.event_booking | Event booking configuration, or nil for a non-event product. |
product.event? | true for a Sellerlane event product. |
product.featured | Merchant-controlled featured-product flag. |
product.featured_image | The featured image. |
product.featured_media | The featured media item. |
product.first_available_variant | First purchasable variant. |
product.gift_card | Boolean alias of gift_card?; true for a Sellerlane gift-card product. |
product.gift_card_denominations | Available gift-card denominations in ascending order. |
product.gift_card_denominations_cents | Available gift-card denominations in currency minor units. |
product.gift_card_info | Gift-card configuration, including supported denominations, or nil. |
product.gift_card? | true for a Sellerlane gift-card product. |
product.gtin | Global Trade Item Number from the merchandising variant. |
product.handle | URL-safe unique slug. |
product.has_only_default_variant | true when the product has no buyer-selectable option combination. |
product.has_price | true when at least one purchasable variant has a finite effective price. |
product.has_price? | Boolean alias of has_price. |
product.id | Unique identifier. |
product.image | Primary image. |
product.image_url | Direct URL of the primary image, or an empty string when no image exists. |
product.images | All images. |
product.in_stock | true when normal post-release inventory rules currently allow stock fulfilment. |
product.is_bundle | true for a Sellerlane bundle product. |
product.is_digital | true for a Sellerlane digital product. |
product.is_event | true for a Sellerlane event product. |
product.is_physical | true for a Sellerlane physical product. |
product.is_published | Explicit storefront publication flag when supplied; otherwise true when a publish timestamp exists. |
product.max_order_qty | Maximum total order quantity, or nil when no maximum is configured. |
product.media | All media (images, video, 3D). |
product.metafields | Metafields on this resource. |
product.min_order_qty | Minimum total order quantity, or nil when no product-level minimum is configured. |
product.modifiers | Typed product modifiers in seller-defined order. |
product.name | Name. |
product.on_sale | true when the purchasable-variant price projection has an effective compare-at price above its lowest effective price. |
product.online_enabled | true when the product is enabled for the online storefront. |
product.options | Option names as an array of strings. Use options_with_values for option definitions and values. |
product.options_by_name | Case-insensitive option lookup keyed by option name. |
product.options_with_values | Options with their values and selection state. |
product.physical? | true for a Sellerlane physical product. |
product.preorder_date | ISO release instant for a preorder, or an empty string when absent. |
product.preorderable | true only while a valid, published preorder is still before its release instant. |
product.preorderable? | Boolean alias of preorderable. |
product.price | Lowest effective price among purchasable variants in currency minor units; falls back to denormalized product pricing when necessary. Format with money. |
product.price_max | Highest effective price among purchasable variants, with a denormalized fallback. |
product.price_min | Lowest effective price among purchasable variants, with a denormalized fallback. |
product.price_unavailable | true when catalog price resolution failed for the signed-in customer and prices were withheld; a transient service state, not a stock-out. |
product.price_unavailable? | Boolean alias of price_unavailable. |
product.price_varies | true when the minimum and maximum values in that purchasable-variant price projection differ. |
product.product_type | Sellerlane product kind such as physical, digital, event, gift_card, or bundle. |
product.published | true when the product is both published and enabled online. |
product.published_at | Publish timestamp. |
product.purchasability | Purchase-mode token: available_now, preorder, contact, or rfq. |
product.quantity_price_breaks_configured | true when any variant exposes a quantity price break. |
product.quantity_price_breaks_configured? | Boolean alias of quantity_price_breaks_configured. |
product.rating | Average published review rating, or nil when no rating is available. |
product.requires_quote | true when the product uses request-for-quote purchasing. |
product.requires_quote? | Boolean alias of requires_quote. |
product.requires_selling_plan | Always false because Sellerlane selling plans are unavailable. |
product.requires_shipping | true when physical delivery is needed. |
product.review_count | Published review count, or nil when review statistics are unavailable. |
product.rfq | true when the product uses request-for-quote purchasing. |
product.rfq_instructions | Seller-authored instructions for requesting a quote. |
product.rfq? | Boolean alias of rfq. |
product.selected_or_first_available_selling_plan_allocation | Always nil because Sellerlane selling plans are unavailable. |
product.selected_or_first_available_variant | The selected variant, else the first available. |
product.selected_selling_plan | Always nil because Sellerlane selling plans are unavailable. |
product.selected_selling_plan_allocation | Always nil because Sellerlane selling plans are unavailable. |
product.selected_variant | Variant selected via URL parameters, or nil. |
product.selling_plan_groups | Always empty because Sellerlane selling plans are unavailable. |
product.seo_description | Translated SEO description, falling back to the product description. |
product.seo_title | Translated SEO title, falling back to the product title. |
product.sku | Stock keeping unit. |
product.tag_names | Product tag strings in deterministic alphabetical order. |
product.tags | Tags as an array of strings. |
product.template_suffix | Assigned alternate template suffix, or nil when the default product template is used. |
product.title | Display title. |
product.type | Merchant-facing product type, falling back to the Sellerlane product_type kind. |
product.upc | Universal Product Code from the merchandising variant. |
product.updated_at | Last update timestamp. |
product.url | Relative URL of the resource. |
product.user_product_type | Merchant-defined product type, separate from Sellerlane product_type. |
product.variant_count | Total supported variant count, including variants beyond the current paginated slice. |
product.variants | The first 250 variants in seller-defined order. Pagination cannot expose variants beyond that cap. |
product.variants_count | Alias of variant_count. |
product.vendor | Vendor / brand name. |
product.videos | Video and external-video media attached to the product. |
product.weight_max | Maximum catalog product weight, or nil when unavailable. |
product.weight_min | Minimum catalog product weight, or nil when unavailable. |
Property names are generated from the storefront engine (ProductDrop), so the
list matches what themes can access. {{ product | json }} is a curated subset;
inspect lazy or omitted properties directly.
Sellerlane differences from Shopify
- Sellerlane models
physical,digital,gift_card,event, andbundleproducts directly. The corresponding capability objects and predicates are Sellerlane extensions. - Purchase modes include immediate purchase, preorder, contact-to-purchase, and request-for-quote. Check the relevant predicates before rendering an add-to-cart action.
- Selling plans are intentionally unsupported.
requires_selling_planisfalse, allocation properties arenil, andselling_plan_groupsis empty. - Sellerlane does not add Shopify B2B, Markets, or app-owned product fields to this object. Quantity breaks come from Sellerlane bulk-pricing tiers.
- Availability uses Sellerlane product-kind, inventory-tracking, backorder, and purchasability rules. Do not assume a Shopify delivery-profile check exists.