Skip to content

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.variants follows seller-defined sort_order and exposes at most 250 variants. Pagination supports a page size of up to 250.
  • product.variants_count reports the full storefront variant count even when the exposed array is capped.
  • product.tags is 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 be nil.
  • product.collections contains only published storefront collections.
  • Prices are integer currency minor units. Format them with money or 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 the product.variants Liquid collection with its 250-item cap.

Properties

PropertyDescription
product.availabletrue 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_nowtrue 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_allowedBackorder policy of the merchandising variant.
product.barcodeBarcode value.
product.bookingEvent booking configuration, or nil for a non-event product.
product.brand_nameMerchant-facing vendor or brand name.
product.bulk_pricing_discount_typeDiscount calculation type used by the active bulk-pricing tiers.
product.bulk_pricing_enabledtrue when at least one bulk-pricing tier applies.
product.bulk_pricing_tiersQuantity tiers ordered by their minimum quantity.
product.bundleBundle configuration for a bundle product, or nil.
product.bundle_itemsResolved items in the active bundle configuration.
product.bundle?true for a Sellerlane bundle product.
product.categoryResolved product taxonomy category, or nil.
product.category_idStored taxonomy category identifier.
product.category_nameMerchant-facing taxonomy category name.
product.collectionsPublished storefront collections containing this product.
product.compare_at_priceLowest 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_maxHighest effective compare-at price among purchasable variants, or nil; falls back to denormalized product pricing when necessary.
product.compare_at_price_minLowest effective compare-at price among purchasable variants, or nil; falls back to denormalized product pricing when necessary.
product.compare_at_price_variestrue when the effective compare-at price differs across the purchasable-variant price projection.
product.contact_purchasetrue when the buyer must contact the seller instead of adding the product to cart.
product.contact_purchase_messageSeller-authored instructions for a contact-to-purchase product.
product.contact_purchase?Boolean alias of contact_purchase.
product.contentBody content (HTML).
product.created_atCreation timestamp.
product.customsCustoms and harmonized-code information, or nil when it does not apply.
product.customs_infoAlias of customs.
product.descriptionDescription (HTML).
product.digital_deliveryDigital-delivery configuration, or nil for a non-digital product.
product.digital?true for a Sellerlane digital product.
product.event_bookingEvent booking configuration, or nil for a non-event product.
product.event?true for a Sellerlane event product.
product.featuredMerchant-controlled featured-product flag.
product.featured_imageThe featured image.
product.featured_mediaThe featured media item.
product.first_available_variantFirst purchasable variant.
product.gift_cardBoolean alias of gift_card?; true for a Sellerlane gift-card product.
product.gift_card_denominationsAvailable gift-card denominations in ascending order.
product.gift_card_denominations_centsAvailable gift-card denominations in currency minor units.
product.gift_card_infoGift-card configuration, including supported denominations, or nil.
product.gift_card?true for a Sellerlane gift-card product.
product.gtinGlobal Trade Item Number from the merchandising variant.
product.handleURL-safe unique slug.
product.has_only_default_varianttrue when the product has no buyer-selectable option combination.
product.has_pricetrue when at least one purchasable variant has a finite effective price.
product.has_price?Boolean alias of has_price.
product.idUnique identifier.
product.imagePrimary image.
product.image_urlDirect URL of the primary image, or an empty string when no image exists.
product.imagesAll images.
product.in_stocktrue when normal post-release inventory rules currently allow stock fulfilment.
product.is_bundletrue for a Sellerlane bundle product.
product.is_digitaltrue for a Sellerlane digital product.
product.is_eventtrue for a Sellerlane event product.
product.is_physicaltrue for a Sellerlane physical product.
product.is_publishedExplicit storefront publication flag when supplied; otherwise true when a publish timestamp exists.
product.max_order_qtyMaximum total order quantity, or nil when no maximum is configured.
product.mediaAll media (images, video, 3D).
product.metafieldsMetafields on this resource.
product.min_order_qtyMinimum total order quantity, or nil when no product-level minimum is configured.
product.modifiersTyped product modifiers in seller-defined order.
product.nameName.
product.on_saletrue when the purchasable-variant price projection has an effective compare-at price above its lowest effective price.
product.online_enabledtrue when the product is enabled for the online storefront.
product.optionsOption names as an array of strings. Use options_with_values for option definitions and values.
product.options_by_nameCase-insensitive option lookup keyed by option name.
product.options_with_valuesOptions with their values and selection state.
product.physical?true for a Sellerlane physical product.
product.preorder_dateISO release instant for a preorder, or an empty string when absent.
product.preorderabletrue only while a valid, published preorder is still before its release instant.
product.preorderable?Boolean alias of preorderable.
product.priceLowest effective price among purchasable variants in currency minor units; falls back to denormalized product pricing when necessary. Format with money.
product.price_maxHighest effective price among purchasable variants, with a denormalized fallback.
product.price_minLowest effective price among purchasable variants, with a denormalized fallback.
product.price_unavailabletrue 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_variestrue when the minimum and maximum values in that purchasable-variant price projection differ.
product.product_typeSellerlane product kind such as physical, digital, event, gift_card, or bundle.
product.publishedtrue when the product is both published and enabled online.
product.published_atPublish timestamp.
product.purchasabilityPurchase-mode token: available_now, preorder, contact, or rfq.
product.quantity_price_breaks_configuredtrue when any variant exposes a quantity price break.
product.quantity_price_breaks_configured?Boolean alias of quantity_price_breaks_configured.
product.ratingAverage published review rating, or nil when no rating is available.
product.requires_quotetrue when the product uses request-for-quote purchasing.
product.requires_quote?Boolean alias of requires_quote.
product.requires_selling_planAlways false because Sellerlane selling plans are unavailable.
product.requires_shippingtrue when physical delivery is needed.
product.review_countPublished review count, or nil when review statistics are unavailable.
product.rfqtrue when the product uses request-for-quote purchasing.
product.rfq_instructionsSeller-authored instructions for requesting a quote.
product.rfq?Boolean alias of rfq.
product.selected_or_first_available_selling_plan_allocationAlways nil because Sellerlane selling plans are unavailable.
product.selected_or_first_available_variantThe selected variant, else the first available.
product.selected_selling_planAlways nil because Sellerlane selling plans are unavailable.
product.selected_selling_plan_allocationAlways nil because Sellerlane selling plans are unavailable.
product.selected_variantVariant selected via URL parameters, or nil.
product.selling_plan_groupsAlways empty because Sellerlane selling plans are unavailable.
product.seo_descriptionTranslated SEO description, falling back to the product description.
product.seo_titleTranslated SEO title, falling back to the product title.
product.skuStock keeping unit.
product.tag_namesProduct tag strings in deterministic alphabetical order.
product.tagsTags as an array of strings.
product.template_suffixAssigned alternate template suffix, or nil when the default product template is used.
product.titleDisplay title.
product.typeMerchant-facing product type, falling back to the Sellerlane product_type kind.
product.upcUniversal Product Code from the merchandising variant.
product.updated_atLast update timestamp.
product.urlRelative URL of the resource.
product.user_product_typeMerchant-defined product type, separate from Sellerlane product_type.
product.variant_countTotal supported variant count, including variants beyond the current paginated slice.
product.variantsThe first 250 variants in seller-defined order. Pagination cannot expose variants beyond that cap.
product.variants_countAlias of variant_count.
product.vendorVendor / brand name.
product.videosVideo and external-video media attached to the product.
product.weight_maxMaximum catalog product weight, or nil when unavailable.
product.weight_minMinimum 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, and bundle products 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_plan is false, allocation properties are nil, and selling_plan_groups is 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.