Cart Transform: Expand Operation
The Expand Lines transform allows you to replace bundled products in the cart with their individual components.
Overview
The Expand Lines transform allows you to replace bundled products in the cart with their individual components. This is particularly useful for:
- 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
When a cart line is expanded, the original bundled item is replaced with a single new line item that represents all the individual components combined together. The customer sees one line item in their cart, but the system processes it as containing multiple components.
How to Configure Expansion
You can configure line expansion in two ways:
- Using the Function Studio Interface: Configure components directly in the expand action using the visual editor
- Using Cart Line Properties: Add component data to your cart lines using the
_componentsproperty
Both methods can be used together - the system will combine components from both sources when expanding your cart lines.
Method 1: Function Studio Configuration
Adding the Expand Action
- In your cart transform function, click Add Action
- Select Expand Lines from the action list
- Configure the action settings in the panel
Configuration Options
Cart Line Groups
- Select which groups of cart lines should be expanded
- Groups must be defined earlier in your function using “Define Cart Line Groups”
- Example: Select “BUNDLE_ITEMS” or “KIT_PRODUCTS”
Component Items For each component you want to add:
- Component Variant: Select the product variant that will be added to the cart
- Quantity: How many of this component per bundle item (default: 1)
- Price Override: Set a fixed price for this component, or leave at 0 to make it free
Bundle Settings
- Apply Bundle Discount: Enable to apply a percentage discount to the entire expanded bundle
- Bundle Discount Percentage: The percentage discount to apply (when enabled). This field supports two modes:
- Static value: Enter a fixed percentage (e.g., 10%)
- Dynamic value: Click the link icon to connect the discount to a metafield, cart attribute, or other input field. This allows different products to have different bundle discount percentages stored in their variant metafields.
- Bundle Image: Optional image URL to display for the expanded items
- Bundle Title: Optional custom title for the expanded items
Method 2: Cart Line Properties Configuration
Overview
You can also configure expansion by adding component data directly to your cart lines using the _components property. This is especially useful for dynamic bundles or when building custom shopping experiences.
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",
"custom_note": "Gift wrapping"
}
},
{
"id": "67890",
"price": "15.50",
"qty": 1,
"properties": {
"material": "Cotton"
}
}
]
Component Object Properties
id (String, Required)
- Product variant ID for the component
- Must be a valid Shopify variant ID
- Example:
"12345"
price (Number, Optional)
- Fixed price per unit for this component
- If omitted, defaults to 0.0
- This becomes the component’s unit price in the expanded cart
qty (Number, Optional)
- Quantity of this component per bundled item
- If omitted, defaults to 1
- Gets multiplied by the bundled item’s quantity
properties (Object, Optional)
- Custom key-value pairs for the component
- Converted to line item attributes in the expanded cart
- Useful for variant options, customizations, or metadata
- Keys and values must be strings
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}]'
}
}
Through Shopify Scripts or Apps
- Set the property when adding items to cart programmatically
- Useful for bundle/kit building applications
- Can be dynamically generated based on customer selections
Advanced Use Cases
Dynamic Bundle Discounts
The bundle price adjustment value can be linked to external data sources instead of using a fixed value:
Supported Sources:
- Variant Metafields: Store discount percentages on each product variant
- Product Metafields: Store discount percentages on the product level
- Cart Attributes: Read discount from cart-level attributes
- Line Item Attributes: Read discount from line item properties
How It Works:
- When you click the link icon next to the discount field, a selector appears
- Choose the data source type (metafield, attribute, etc.)
- Select the specific field to use
- At runtime, the function reads the value from that field for each cart line
Benefits:
- Configure different discounts per product without creating multiple functions
- Update discounts by changing metafield values (no function redeployment needed)
- Support complex promotional scenarios with varying discount levels
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:
How It Works:
- The system calculates the total bundle price from all component prices (sum of unit_price × quantity)
- Applies the percentage discount to get the discounted bundle total
- Distributes the discounted total across components proportionally based on their original price weight
- 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%
- Original total: $100
- Discounted total: $90
- Component A final price: $54 (60% of $90)
- Component B final price: $36 (40% of $90)
This ensures accurate pricing while respecting Shopify’s API constraints.
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: Single line item containing 6 total components (3 × 2 = 6)
Component Properties to Line Item Attributes
Properties from the _components data become line item attributes in the expanded cart:
Component Configuration:
{
"id": "123",
"properties": {
"engraving": "John Smith",
"gift_wrap": "true"
}
}
Resulting Line Item: Will have custom attributes for “engraving” and “gift_wrap” that can be used by your theme or other systems.
Combined Configuration Sources
The system automatically combines components from both sources:
Function Studio: Always adds the components you configure in the interface
Cart Properties: Plus any components from _components properties on cart lines
Result: All components from both sources are included in the expansion
Configuration Examples
Example 1: Function Studio Configuration
Scenario: A “Starter Kit” bundle should expand into its individual components
Function Studio Setup:
- Create a “Define Cart Line Groups” action with group name “STARTER_KITS”
- Add an “Expand Cart Lines” action with:
- Cart Line Groups: Select “STARTER_KITS”
- Component Items:
- T-shirt variant, Quantity: 1, Price: $25.99
- Cap variant, Quantity: 1, Price: $15.99
- Stickers variant, Quantity: 2, Price: $5.99
- Bundle Settings: No bundle discount
Result: Bundle item replaced with a single line item containing all 3 components (T-shirt, Cap, 2x Stickers) with combined pricing
Example 2: Cart Properties Configuration
Scenario: Products with _components property are automatically expanded
Cart Line Setup: Add this to your product form or set via cart API:
{
"id": "999",
"quantity": 2,
"properties": {
"_components": '[{"id":"111","price":"25.99","qty":1,"properties":{"size":"L","color":"Blue"}},{"id":"222","price":"15.99","qty":1,"properties":{"style":"Baseball"}}]'
}
}
Function Studio Setup:
- Create a “Define Cart Line Groups” action with group name “COMPONENT_BUNDLES”
- Add an “Expand Lines” action with:
- Cart Line Groups: Select “COMPONENT_BUNDLES”
- Component Items: Leave empty (components come from cart properties)
- Read from properties Switch it ON
- Bundle Settings: Configure as needed
Result:
- Original bundle (qty 2) becomes a single expanded line item containing:
- 2x T-shirt components (Large, Blue)
- 2x Cap components (Baseball style)
- Combined pricing from both component types
Example 3: Combined Configuration with Bundle Discount
Scenario: Use both Function Studio components and cart properties with a bundle discount
Function Studio Setup:
- Create a “Define Cart Line Groups” action with group name “PREMIUM_BUNDLES”
- Add an “Expand Lines” action with:
- Cart Line Groups: Select “PREMIUM_BUNDLES”
- Component Items: Add premium accessory variant, Quantity: 1, Price: $49.99
- Bundle Settings:
- Enable “Apply Bundle Discount”
- Set discount to 10%
- Add bundle image URL
- Set title to “Premium Bundle Components”
Plus Cart Properties: Items also have _components property with additional components
Example 4: Pricing Options
Function Studio Pricing:
- Set “Price Override” to $19.99 → Component will cost exactly $19.99
- Leave “Price Override” at 0 → Component uses its original product price
Cart Properties Pricing:
{"id": "555", "price": "24.99"}
→ Component will cost exactly $24.99
No Custom Pricing:
- Don’t set price in Function Studio
- Don’t include “price” in cart properties → Component uses its original Shopify product price
Example 5: Dynamic Bundle Discount from Metafield
Scenario: Different bundle products have different discount percentages stored in a variant metafield
Metafield Setup:
- Create a variant metafield with namespace
customand keybundle_discount - Set the metafield type to
number_decimal - Add different discount values to each bundle variant (e.g., 10, 15, 20)
Function Studio Setup:
- Create a “Define Cart Line Groups” action with group name “BUNDLES”
- Add an “Expand Lines” action with:
- Cart Line Groups: Select “BUNDLES”
- Bundle Settings:
- Enable “Apply Bundle Discount”
- Click the link icon next to the discount percentage field
- Select “Variant Metafield” and choose
custom.bundle_discount
Result: Each bundle product will be expanded with its own specific discount percentage pulled from the variant metafield. A bundle with bundle_discount: 15 gets 15% off, while another with bundle_discount: 20 gets 20% off.
Best Practices
Planning Your Bundle Strategy
- Decide whether to use Function Studio configuration, cart properties, or both
- Use Function Studio for consistent, predictable components
- Use cart properties for dynamic, customizable bundles
- Test your configuration with different cart scenarios
Component Selection
- Ensure all component variants exist and are available
- Choose appropriate quantities for each component
- Consider how pricing affects the customer experience
- Test with various bundle quantities in cart
Pricing Strategy
- Use Function Studio price overrides for promotional pricing
- Use cart properties pricing for dynamic component pricing
- Leave pricing blank to use original product prices
- Apply bundle discounts for overall promotional pricing
Customer Experience
- Use meaningful bundle titles and images since customers see the bundle as one item
- The total price combines all component pricing but individual component prices are hidden
- Test the checkout experience with expanded bundles
- Consider how the bundled components appear in order confirmations
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
- Test what happens when components are out of stock
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
- Customers see one line item but it contains all the individual components
- Individual component prices are not visible to customers
Data Format Requirements
- Cart properties must contain valid JSON
- Component IDs must be numeric parts from the Shopify variant IDs (gid://shopify/ProductVariant/123 -
123) - Property keys and values must be strings
- Quantities must be positive numbers
Function Flow Requirements
- Cart line groups must be defined before the expand action
- Expansion happens during cart processing
- Changes apply to the current cart session
Troubleshooting
Expansion Not Working
- Check your groups: Make sure you’ve defined the cart line groups correctly before the expand action
- Verify variant IDs: Ensure all component variant IDs exist in your store
- Test the function: Use the Function Studio tester to preview the expansion
- Start simple: Begin with basic expansion and add complexity gradually
Cart Properties Issues
- Check JSON format: Ensure your
_componentsproperty contains valid JSON - Verify variant IDs: Make sure all component IDs are correct
- Test the property: Add the property to a test cart and verify it’s set correctly
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
Pricing Problems
- Verify price format: Ensure prices are text strings in the attributes, not numbers
- Check bundle discounts: Confirm bundle discount percentages are between 0-100
- Test different scenarios: Try expansion with various price configurations
Cart Display Issues
- Clear your cart: Remove test items and try again
- Check inventory: Ensure component products have sufficient stock
- Review bundle presentation: The expanded bundle appears as one line item with combined pricing
Using with Other Actions
Required Setup
- Define Cart Line Groups: Always create your groups before adding the expand action
- Test your groups: Use other actions to verify your groups contain the right items
Additional Actions
- Apply discounts: You can discount the expanded bundle with additional discount actions
- Update bundles: Use line update actions to modify the expanded bundle further
- Conditional expansion: Use conditions to expand only when certain criteria are met
Integration Tips
- Place the expand action after group definitions but before discount actions
- Test your complete function flow with realistic cart data
- Consider the order of operations when combining multiple actions
The expand lines action provides powerful flexibility for creating dynamic bundle experiences while maintaining full control over pricing and customer presentation.