--- title: Create a bundle app description: Learn how to create a bundle app and get familiar with the Shopify bundles sample app. source_url: html: https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app md: https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app.md --- ExpandOn this page * [What you'll learn](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#what-youll-learn) * [Requirements](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#requirements) * [Metafields versus line item properties](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#metafields-versus-line-item-properties) * [Step 1: Install the Shopify bundles sample app](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#step-1-install-the-shopify-bundles-sample-app) * [Step 2: Model a bundle](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#step-2-model-a-bundle) * [Step 3: Enable the bundle through extensions](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#step-3-enable-the-bundle-through-extensions) * [Next steps](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#next-steps) # Create a bundle app The Shopify bundles sample app is an example of how to build a bundle app, and shows an implementation of a `cart_transform` function to update the cart. It also shows how to do merge and expand transformations, and offers guidance on UI extensions to render bundles. *** ## What you'll learn In this tutorial, you'll learn how to do the following tasks: * Install the Shopify bundles sample app. * Model a bundle by creating metafields on variants, creating a bundle parent product variant, and defining the bundle on child product variants. * Enable the bundle through extensions. *** ## Requirements * You're a [user with app development permissions](https://shopify.dev/docs/apps/build/dev-dashboard/user-permissions) and have created a [development store](https://shopify.dev/docs/api/development-stores#create-a-development-store-to-test-your-app). *** ## Metafields versus line item properties When you build custom bundles with cart transforms, you can store bundle data using metafields or line item properties. Choose metafields when you need secure, merchant-defined bundles with fixed compositions. Choose line item properties when you need flexible, buyer-customizable bundles, but ensure you implement proper validation and don't rely solely on the properties for critical business logic. | | Metafields | Line item properties | | - | - | - | | Best for | Fixed bundles where the bundle composition is predetermined by the merchant | Mix-and-match bundles where buyers can customize the bundle composition | | Pros | * More secure as metafield data cannot be modified by the browser * Bundles with a fixed-set of merchant defined components means you know exactly what each bundle contains and don't need to validate that the bundle contains permitted variants and quantities selected | - Enables dynamic bundle creation based on buyer selections - Supports mix-and-match functionality without predefined variants - Allows buyers to customize quantities and variants within a bundle - More flexible for complex bundle configurations | | Cons | * Buyers cannot pick and choose the quantities or variants unless those combinations are pre-defined * Requires creating and managing metafield definitions * Each bundle variation needs to be predefined as a separate product variant | - Line item properties can be modified by the browser, so they should not be relied upon for security or validation purposes - Requires additional validation logic in your cart transform function - May need extra UI components to manage bundle selections | *** ## Step 1: Install the Shopify bundles sample app The sample app is currently published under the Shopify organization, and available for installation on stores. 1. Navigate to the Shopify bundles sample app's [installation URL](https://shopify-bundles-reference.shopifysvc.com/auth), and enter your development store's storefront URL into the text box. You're redirected to the Shopify admin for the store and prompted to install the app. 2. Click **Install app**. *** ## Step 2: Model a bundle You model a bundle by creating metafields on variants, creating a bundle parent product variant, and defining the bundle on child product variants. ### Create metafields on product variants 1. In the Shopify admin, go to **Settings**. 2. Click **Custom data** in the side navigation. Note The button might say **Metafields** depending on your store's settings. 3. Under **Metafields**, click **Variants**. 4. Click **Add definition** to create the following metafield definitions and click **Save**: `component_reference` metafield definition: | Field | Value | | - | - | | Name | `component_reference` | | Namespace and key | `custom.component_reference` (Don't change the default) | | Description | `Components included in Bundle` | | Select type | `Product Variant` - `List of product variants` | `component_quantities` metafield definition: | Field | Value | | - | - | | Name | `component_quantities` | | Namespace and key | `custom.component_quantities` (Don't change the default) | | Description | `Quantity of components included in Bundle` | | Select type | `Integer` - `List of values` | | Validation | `Minimum value` - `1` | `component_parents` metafield definition: | Field | Value | | - | - | | Name | `component_parents` | | Namespace and key | `custom.component_parents` (Don't change the default) | | Description | `Child component parent definition` | | Select type | `JSON` | | Rules | Refer to the JSON rules example. | ## JSON rules ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Bundle component parents", "description": "A definition of the bundle a child belongs to", "type": "array", "items":{ "type": "object", "properties": { "id": { "description": "ID of bundle parent product variant: gid://shopify/ProductVariant/", "type": "string" }, "component_reference": { "type": "object", "properties": { "value": { "description": "Array of product variant IDs: [gid://shopify/ProductVariant/]", "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true } } }, "component_quantities": { "type": "object", "properties": { "value": { "description": "Array of quantities of product variants defined in component_reference: [1]", "type": "array", "items": { "type": "integer" }, "minItems": 1 } } } } }, "required": [ "id", "component_reference", "component_quantities" ] } ``` ### Create a bundle parent product variant 1. Create 2 separate products that will be a part of the bundle. The products should have the following requirements: * At least one available in inventory * Price is more than 0 * At least one option, since you'll need access to the product variant 2. Create a product that represents the bundle with the following requirements: * At least one available in inventory * Price is more than 0 * At least one option, since you'll need access to the product variant. 3. After saving the product, click **Edit** next to the variant of the option. This will be a bundle parent product variant. 4. Scroll to the **Metafields** section of the variant edit page. 5. Open up the product variants that will be included in the bundle in separate browser tabs. Note You'll need access to the product variant IDs of the bundled products while defining them. The product variant IDs can be found in the URL of the product variant: `https://admin.shopify.com/store//products//variants/`. 6. On the parent product variant page, click the `component_reference` field under **Metafields**. 7. Select the product variants that will be bundled, and then click **Save**. 8. Select the `component_quantities` field under **Metafields**. Note Add a quantity for each `component_reference` in the bundle. The order matters, as the quantity entered will correspond with the `component_reference` entered. 9. Click **Save** on the parent product variant page. Caution Don't exit this page, as you'll need the ID from the URL. ### Define the bundle on child product variants Complete the following steps for each children product variant defined in `component_reference` in the previous step: 1. On the child product variant page, click the `component_parents` field under **Metafields**. 2. Using the JSON schema defined, build the bundle definition. Note The `component_reference` and `component_quantities` values must match the values defined on the parent in the previous step. ## Example ```json [ { "id": "gid://shopify/ProductVariant/", "component_reference": { "value": [ "gid://shopify/ProductVariant/", "gid://shopify/ProductVariant/" ] }, "component_quantities": { "value": [ , ] } } ] ``` *** ## Step 3: Enable the bundle through extensions The `bundle-cart-transform` extension uses the `cart_transform` function in Shopify to update the cart. The sample app uses the extension to do two transformations: * Merge the bundle * Expand the bundle ### Merge the bundle If the extension detects all of the components of a given bundle in the cart at checkout, then the extension returns `linesMerge` operations to Shopify that combine the respective components and present the given `parent_product_variant`. In the reference app, the `linesMerge` functionality reads over all of the `product_variants`, and looks for the `metafield` with the following properties: `namespace: "custom", key: "component_parents"`. This query is defined in `extensions/bundle-cart-transform/src/run.graphql`: ## Query ```graphql query Input { cart { lines { id quantity merchandise { ... on ProductVariant { id component_parents: metafield( namespace: "custom" key: "component_parents" ) { value } } } } } } ``` `component_parents` is a `metafield` on `product_variant` with the content type `JSON`. Its `value` is an array of objects defining the bundle rules. For the `linesMerge` function to work in the sample app, each child belonging to a bundle must have `component_parents` defined. A bundle rule has the following shape: ## Bundle rule ```json { "id": , "component_reference": { "value": }, "component_quantities": { "value": } } ``` For example, you might have a bundle that contains two shirts and one pair of pants. The bundle parent `product_variant` ID is `6`, the shirt `product_variant` ID included in the bundle is `3` and the pants `product_variant` ID included in the bundle is `4`. The following example shows the value of the `component_parents` metafield that must belong to both the shirt `product_variant` and pants `product_variant` for the `linesMerge` functionality in the extension to work. ## Example ```json [ { "id": "gid://shopify/ProductVariant/6", "component_reference": { "value": [ "gid://shopify/ProductVariant/3", "gid://shopify/ProductVariant/4" ] }, "component_quantities": { "value": [ 2, 1 ] } } ] ``` The order of the `component_reference` and the `component_quantities` match up. In the example, the first `component_quantities` value (`2`) matches with the first `component_reference` value (`gid://shopify/ProductVariant/3`) because two shirts are required for the bundle to be complete. Notice that the extension uses Shopify's `product_variant` GIDs. The ID of the `product_variant` must be prepended with `gid://shopify/ProductVariant/` to denote that it's a `product_variant` ID. ### Rendering bundles in storefront Bundles apps are responsible for managing product variants and options. Bundles apps need to create user interface product management flows to do the following: * Create a new product. At least one bundle configuration must be created. * Update an existing product. These pages must be implemented using [Shopify App Bridge](https://shopify.dev/docs/api/app-bridge). ### Creating an app block If your bundles app needs to customize the storefront, then you need to create an app block that encapsulates that logic. Learn how to create an app block using [theme app extensions](https://shopify.dev/docs/apps/build/online-store/theme-app-extensions). *** ## Next steps * Learn more about how [Shopify Functions](https://shopify.dev/docs/api/functions/current) work and the benefits of using Shopify Functions. * Consult the [API references for Shopify Functions](https://shopify.dev/docs/api/functions). * Learn how to use [variables](https://shopify.dev/docs/apps/build/functions/input-queries/use-variables-input-queries) in your input query. *** * [What you'll learn](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#what-youll-learn) * [Requirements](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#requirements) * [Metafields versus line item properties](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#metafields-versus-line-item-properties) * [Step 1: Install the Shopify bundles sample app](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#step-1-install-the-shopify-bundles-sample-app) * [Step 2: Model a bundle](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#step-2-model-a-bundle) * [Step 3: Enable the bundle through extensions](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#step-3-enable-the-bundle-through-extensions) * [Next steps](https://shopify.dev/docs/apps/build/product-merchandising/bundles/create-bundle-app#next-steps)