Packing slips
Group a bundle's components under one header with its SKU and item count on your Shopify packing slip template.
On a packing slip, Shopify lists a merged box's components as separate rows and only stamps Part of: … on each one — there's no grouped block. This code rebuilds the grouping the packing slip doesn't do.
Where to edit: Shopify admin → Settings → Shipping and delivery → Packing slips → Edit packing slip template.
Back it up first
Select everything in the editor and paste it into a text file before you change anything. There's no version history for this template.
The result
Instead of six loose rows, the slip prints one bordered block per box: the bundle's name, its SKU and item count in the header, then the components indented beneath it. Non-bundle products in the same order print exactly as they did before.
Step 1 — Collect the bundles in this shipment
Put this above the line item loop. It walks the lines once and records each bundle's identity.
Liquid has no arrays you can push to, so the ids are glued into one string with a ~|~ separator and split back apart. uniq collapses the duplicates — every component of the same box contributes the same id.
The key is the app's _bundle_id property, which every Bundle Builder line carries in both cart line modes. Don't use the bundle's name as the key: two boxes from the same builder share a name and would collapse into one block.
Step 2 — Print the non-bundle lines
Your existing single loop stays exactly as it is, with one condition added inside it: skip any line that carries a _bundle_id.
Keep the Part of: … line in this block. It still applies to bundles that don't come from Bundle Builder.
Step 3 — Print one block per bundle
Put this right after the loop from step 2. For each id collected in step 1, it scans the lines twice: once to work out the header (name, SKU, item count), once to render the components.
How each header value is resolved:
- Name — the native group title (a merged box); for individual mode it's pulled out of the
_oxify_builderproperty by string-splitting on"n":"(Liquid can't parse JSON), then_bundle_name(older merged lines), then literally "Bundle". - SKU — the visible
Bundle SKUproperty, which is your parent product's SKU. It's shown once in the header instead of on every row, so the component rows should suppress it (see below). - Count — the components'
shipping_quantity, summed. A box that ships in more than one parcel is counted per shipment: each slip lists only the components in its own shipment.
In the component markup, delete the Part of: … line (the header already says it) and suppress the SKU so it isn't repeated on every row. If the markup prints line item properties, use this loop for them — it skips Bundle SKU and every property whose name starts with an underscore:
Step 4 — The CSS
Append these to the end of the template's existing <style> block. page-break-inside: avoid keeps a bundle from splitting across two printed pages.
Everything else in the template — header, addresses, notes, footer, the original CSS — stays untouched.
Showing the bundle's image
Packing slips don't print product images by default, but if yours does, know what's actually available: the bundle's own image is not reliably on the order lines, only the component images are.
line_item.imageon each component is the component's photo, and it's always there._bundle_image_url— the image you set in the builder's General Settings — is written to the line only on older, legacy-format lines. On current merged-mode orders it isn't present, because that value now lives in the app's Cart Transform configuration rather than on the cart line. Individual-mode lines never carry it.
So the safe recipe is: use the bundle image if the property happens to exist, and fall back to the first component's photo. Put this inside the {% for oxify_bundle_key in oxify_keys %} loop, above the <div class="ia-bundle-group">:
Drop the <img> into .ia-bundle-group-header next to the title.
Why there's no property for the real bundle image
The bundle image is kept on the hidden parent product in Shopify and in the app's Cart Transform configuration, not on the order lines, so there's nothing on a line for a template to read. Orders keep showing the component photo.
The preview lies
The preview in the packing slip editor doesn't include line item properties, so the SKU line looks missing there. Only a real print — Orders → More actions → Print packing slips — shows the true output. Always test with a real order that contains a bundle.
Next
Notification emails — the same idea for order confirmation and shipping emails.