OxifyOxify

The properties

The line item properties Bundle Builder writes on every component line — what each one means, and which ones your templates should read.

Grouping in Liquid works because every product added from a builder carries identifying properties. This page is the reference; the template pages use them.

The ones you should read

PropertyExampleWhat it's for
Bundle SKUBOX-COFFEE-6Visible, human-facing. Your parent product's SKU. Only present when the setting is on.
_bundle_idbundle-42-1717070000The grouping key. Unique per box the shopper built — two boxes from the same builder in one order get two different ids, so they render as two groups.
_bundle_builder_id42Which builder the box came from. Use it if you want different markup per builder.
_slot_index0, 1, 2Position in the box.

The ones that may or may not be there

These exist for the app's own pricing and merging logic. Read them only as fallbacks, and always guard with != blank.

PropertyWhen it's present
_oxify_builderIndividual cart-line mode only. A compact JSON string holding the bundle name and discount.
_bundle_cart_modeIndividual mode only — the value is individual.
_bundle_discountMerged mode, current format, e.g. percentage:50.
_bundle_name, _bundle_image_url, _bundle_parent_variant, _bundle_discount_type, _bundle_discount_valueMerged mode, legacy format only — stores that haven't republished since the compact format shipped. Don't rely on _bundle_name or _bundle_image_url being there; fall back to the first component's image.

Underscored properties are hidden from customers, not from you

Shopify hides _-prefixed properties on the storefront and in emails, but they are always visible on the admin order page. That's a Shopify behaviour with no way to turn it off — it's why the app writes as few of them as it can.

Getting the bundle's name

There is no single property that always holds the name, so templates resolve it in this order:

Native group title. On packing slips, a merged bundle exposes line_item.groups; the non-deliverable group's title is the bundle's name.

_oxify_builder. In individual mode, split the JSON string on "n":" and take what's before the next quote — Liquid can't parse JSON, so string-splitting is the only option.

_bundle_name. Present on legacy merged-mode lines.

A literal fallback, like Bundle.

Each template page implements this chain for you — you don't have to write it yourself.

Reading a property in Liquid

Two syntaxes, both valid. Use the bracket form when the name has a space or starts with an underscore:

{{ line_item.properties["Bundle SKU"] }}
{{ line_item.properties._bundle_id }}

To hide the raw properties from a row you're rendering yourself, skip the ones you've already displayed in the header (Shopify already hides _-prefixed properties from customer-facing output):

{% for property in line_item.properties %}
  {% unless property.last == blank
      or property.first == 'Bundle SKU'
      or property.first == '_bundle_id'
      or property.first == '_bundle_builder_id' %}
    {{ property.first }}: {{ property.last }}
  {% endunless %}
{% endfor %}

Next

Packing slips — the full worked example.

On this page