Skip to main content

Bundle Apps Compatibility

Written by Haris Spahovic

Shopify Bundles (Line Items)

The line_item object now includes specialized properties to identify and handle Shopify Bundles. This allows you to display a breakdown of individual components within a bundle on orders, invoices, and packing slips.

New Properties

Property

Type

Description

line_item.is_bundle

Boolean

Returns true if the line item is a Shopify-native bundle.

line_item.components

Array

A list of individual products within the bundle. Returns an empty array [] for standard items.

Component Schema

Each object within the line_item.components array contains the following attributes:

  • title (String): The name of the component product.

  • variant_title (String): The specific variant name (e.g., "Blue / Large").

  • sku (String): The SKU assigned to the component.

  • quantity (Integer): The number of units of this component included in a single bundle.

  • price (Integer): The individual price of the component in cents.

  • line_price (Integer): The total price for this component ($price \times quantity$) in cents.

  • variant_id (Integer): The unique Shopify ID for the variant.

  • requires_shipping (Boolean): Indicates if the component is a physical good requiring shipment.


Implementation Example

Use the following Liquid pattern to render a component breakdown only when a bundle is detected.

In order for bundle products to show in your Live order template, please include this code in your template editor:

 {% for line_item in line_items %}
{% if line_item.is_bundle %}
<tr>
<td>
<strong>{{ line_item.title }}</strong>
{% if line_item.variant_title != blank %} — {{ line_item.variant_title }}{% endif %}
<br>
<small>Bundle × {{ line_item.quantity }}</small>

<ul style="margin: 4px 0 0 16px; padding: 0; list-style: disc;">
{% for component in line_item.components %}
<li>
{{ component.title }}
{% if component.variant_title != blank %} — {{ component.variant_title }}{% endif %}
<br>
<small>
SKU: {{ component.sku }} |
Qty: {{ component.quantity }} × {{ component.price | money }} = {{ component.line_price | money }}
</small>
</li>
{% endfor %}
</ul>
</td>
<td>{{ line_item.quantity }}</td>
<td>{{ line_item.line_price | money }}</td>
</tr>
{% else %}
<tr>
<td>
{{ line_item.title }}
{% if line_item.variant_title != blank %} — {{ line_item.variant_title }}{% endif %}
<br>
<small>SKU: {{ line_item.sku }}</small>
</td>
<td>{{ line_item.quantity }}</td>
<td>{{ line_item.line_price | money }}</td>
</tr>
{% endif %}
{% endfor %}

Key points for merchants:
- line_item.is_bundle — true for the bundle parent; use this to branch rendering
- line_item.components — array of the individual products in the bundle
- component.price — unit price of each component
- component.line_price — price × quantity for that component
- line_item.line_price — total bundle price (sum of all components)
- Non-bundle line items follow the normal {% else %} path — no changes needed there

Did this answer your question?