Cart Transform: Expand Operation

Cart Transform: Expand Operation

Replace bundled products in the cart with their individual components

Overview

The Expand Lines block replaces bundled products in the cart with their individual components. The customer sees one line item in their cart, but the system processes it as containing multiple components.

  • Product bundles — break down bundle products into their individual items
  • Kit products — expand kits to show individual components with custom pricing
  • Custom component products — transform products with attached component data into separate line items
  • Dynamic pricing — apply per-variant pricing from metafield mappings

Two Methods

Components can come from two sources, and both can be used together:

  • Function Studio configuration — define components directly in the block using the visual editor
  • Cart line properties — attach component data to cart lines via the _components property (set by your theme, app, or storefront)

Setup

Open your cart transform function

Navigate to the function you want to edit in Function Studio

Add the Expand Lines block

Click Add Action and select Expand Lines from the action list

Configure the block

Set the options described in the Settings section below


Settings

Cart Line Groups

Required

Select which groups of cart lines should be expanded. Groups must be defined earlier in your function using a Define Cart Line Groups block.

Component Items

Define the component items that will be added to the selected cart line. For each component:

Component Variant

Required

Select the product variant that will be added to the cart.

Quantity

How many of this component per bundle item (default: 1). When the bundled item has a quantity greater than 1, component quantities are automatically multiplied.

Component Price Override

Set a fixed price for this component, or leave at 0 to use the original product price. Hidden when Apply Bundle Discount is enabled — component prices are then controlled by the bundle discount instead.

Read From Attributes

Optional

When enabled, the block reads component data from the _components cart line property in addition to any components configured in Function Studio. See Cart Line Properties Configuration below.

Apply Bundle Discount

When enabled, a percentage discount is applied to the entire expanded bundle. Individual component price overrides are hidden — the discount applies to the bundle total instead.

Bundle Price Adjustment

Shown when Apply Bundle Discount is enabled

The percentage discount to apply to the bundle (0–100%). This field supports two modes:

  • Static value — enter a fixed percentage (e.g., 10%)
  • Linked value — click the link icon to connect the discount to a metafield, cart attribute, or line property. This allows different products to have different bundle discount percentages.
Note

Linking this field requires the Advanced plan.

Bundle Image

Optional

Custom image for the expanded bundle product.

Bundle Title

Optional

Custom display title for the expanded bundle.


Cart Line Properties Configuration

You can configure expansion by adding component data directly to your cart lines using the _components property. Enable Read from attributes in the block settings to use this method.

Components JSON Structure

The _components attribute should contain a JSON array of component objects:

[
  {
    "id": "12345",
    "price": "29.99",
    "qty": 2,
    "properties": {
      "color": "Red",
      "size": "Large"
    }
  },
  {
    "id": "67890",
    "price": "15.50",
    "qty": 1,
    "properties": {
      "material": "Cotton"
    }
  }
]

Component Fields

id

Required

Product variant ID for the component. Must be the numeric part of the Shopify variant GID — e.g., "12345" from gid://shopify/ProductVariant/12345.

price

Optional

Fixed price per unit for this component. If omitted, defaults to 0. This becomes the component’s unit price in the expanded cart.

qty

Optional

Quantity of this component per bundled item. If omitted, defaults to 1.

properties

Optional

Custom key-value pairs for the component. Converted to line item attributes in the expanded cart. Keys and values must be strings.

Object Format with Per-Line Overrides

Instead of a plain array, you can use an object format that includes per-line overrides for the bundle image, title, and discount percentage. The system auto-detects which format you’re using.

{
  "image": "https://cdn.shopify.com/bundle-image.jpg",
  "title": "Custom Bundle Title",
  "percentageDecrease": 20,
  "items": [
    {"id": "12345", "price": "29.99", "qty": 2, "properties": {"color": "Red"}},
    {"id": "67890", "price": "19.99", "qty": 1}
  ]
}

image

Optional

Bundle image URL for this specific cart line. Overrides the global bundle image configured in Function Studio.

title

Optional

Bundle title for this specific cart line. Overrides the global bundle title.

percentageDecrease

Optional

Bundle percentage decrease for this specific cart line (e.g., 20 means 20% off). Overrides the bundle discount configured in Function Studio. Set to 0 to explicitly remove the discount for this line.

items

Required

Component items using the same format as the array format described above.

Setting the Components Property

The _components property can be set through various methods:

In Product Forms (Liquid Templates)

<input type="hidden" name="properties[_components]" value='[{"id":"12345","price":"29.99","qty":2}]'>

Via Ajax Cart API

{
  "id": "12345",
  "qty": 1,
  "properties": {
    "_components": '[{"id":"12345","price":"29.99","qty":2}]'
  }
}

How It Works

Weighted Price Allocation

When you use both component-level fixed prices and a bundle discount percentage, Shopify doesn’t allow combining these directly. Function Studio automatically handles this by using a weighted price allocation algorithm:

Calculate total

The system sums all component prices (unit price × quantity)

Apply discount

The percentage discount is applied to the total

Distribute proportionally

The discounted total is distributed across components based on their original price weight

Set final prices

Each component’s final price is set to their allocated share

Example:

  • Component A: $60 (weight: 60%)
  • Component B: $40 (weight: 40%)
  • Bundle discount: 10%
  • Discounted total: $90
  • Component A final price: $54 (60% of $90)
  • Component B final price: $36 (40% of $90)

Dynamic Component Quantities

When the bundled item has a quantity greater than 1, component quantities are automatically multiplied:

  • Bundle in cart: Quantity 3
  • Component configuration: Quantity 2 per bundle
  • Result: 6 total components (3 × 2)

Combined Configuration Sources

When both Function Studio components and cart line properties are used, the system combines components from both sources. Function Studio components are added first, then any components from the _components property.


Examples

Example 1: Static Components (Function Studio)

A “Starter Kit” bundle expands into its individual components.

Create a cart line group

Add a “Define Cart Line Groups” block with group name STARTER_KITS

Add the Expand block

Select Expand Lines and set Cart Line Groups to STARTER_KITS

Add components

Add T-shirt variant (qty 1, $25.99), Cap variant (qty 1, $15.99), and Stickers variant (qty 2, $5.99)

Result

Bundle item is replaced with a single line item containing all 3 components with combined pricing

Example 2: Dynamic Components from Cart Properties

Products with a _components property are automatically expanded.

Create a cart line group

Add a “Define Cart Line Groups” block with group name COMPONENT_BUNDLES

Add the Expand block

Select Expand Lines, set Cart Line Groups to COMPONENT_BUNDLES, and enable Read from attributes

Leave Component Items empty

Components come from the cart line’s _components property

Result

Each bundle is expanded using the component data attached to the cart line

Example 3: Dynamic Bundle Discount from Metafield

Different bundle products have different discount percentages stored in a variant metafield.

Set up metafields

Create a variant metafield custom.bundle_discount (type: number_decimal) and set values per variant

Create the group and block

Add a “Define Cart Line Groups” block for bundles, then an “Expand Lines” block

Enable bundle discount

Turn on Apply Bundle Discount, then click the link icon next to the discount field and select custom.bundle_discount

Result

Each bundle product is expanded with its own discount percentage pulled from the variant metafield

Example 4: Price Mapping from Variant Metafield

Use a Variant Price Mapping block to apply dynamic per-component pricing from a CSV metafield.

Add a Variant Price Mapping block

Place it before the Expand block. Configure it to read from the variant metafield containing pricing data

Add the Expand block

In the Price Mapping dropdown, select the mapping variable created by the Variant Price Mapping block

Result

Component prices are dynamically looked up from the metafield CSV data at runtime, overriding static price overrides


Best Practices

Component Setup

  • Ensure all component variants exist and are published in your store
  • Consider inventory management — component products may need separate stock tracking
  • Test with different cart quantities to verify component multiplication

Pricing Strategy

  • Use percentage discounts to incentivize bundles over individual purchases
  • When using linked fields for the discount, ensure the linked field always resolves to a valid number between 0 and 100
  • Use Price Mapping when you need per-variant component pricing that can be updated without redeploying the function

Customer Experience

  • Use meaningful bundle titles so customers understand what they’re purchasing
  • Provide a bundle image that represents the combined items
  • The customer sees one line item — individual component prices are not visible

Important Considerations

Product Availability

  • All component variants must exist in your store
  • Components must be available (not archived or deleted)
  • Consider inventory levels for component products

Cart Behavior

  • Original bundle items are completely replaced by the expanded bundle
  • All components are merged into a single line item in the cart
  • Cart totals reflect the combined pricing of all components
  • Individual component prices are not visible to customers

Data Format Requirements

  • Cart properties must contain valid JSON
  • Component IDs must be the numeric part of Shopify variant GIDs (e.g., 12345 from gid://shopify/ProductVariant/12345)
  • Property keys and values must be strings
  • Quantities must be positive numbers

Plan Requirements

  • Linking the Bundle Price Adjustment field to a metafield or attribute requires the Advanced plan

Troubleshooting

Expansion Not Working

  • Check your groups — review conditions in your line item groups
  • Verify variant IDs — ensure all component variant IDs exist in your store
  • Start simple — begin with basic expansion and add complexity gradually

Cart Properties Issues

  • Check JSON format — ensure the _components property contains valid JSON
  • Verify variant IDs — make sure all component IDs are correct numeric IDs
  • Enable Read from attributes — the toggle must be on for cart properties to be read
  • Test the property — add the property to a test cart and verify it’s set correctly

Pricing Problems

  • Verify price format — prices in _components JSON should be strings (e.g., "29.99")
  • Check bundle discounts — confirm discount percentages are between 0 and 100

Components Not Appearing

  • Check group matching — verify your cart items match the group conditions
  • Review component data — ensure component variants are available and not archived
  • Test step by step — use the function tester to see which components are being processed