# Bundles: Developer Documentation

Last updated: May 14, 2025

{% hint style="warning" %}
For information on how to set up Bundles within the Smartrr app, view: 🧺 [<mark style="color:blue;">What are Bundles?</mark>](https://help.smartrr.com/docs/support/admin-portal/bundles)\
\
If you're on our 💎 Excel plan, our implementation team can set up bundles on your storefront for you. The below provides supporting technical documentation that can be used by in-house developers.&#x20;
{% endhint %}

The ability to trigger the bundle-builder modal can be placed anywhere on your site. For example, it can live on a parent bundle PDP as a CTA button: "**Build my bundle**".&#x20;

### Initial Setup

Once Subscription Programs and Bundles have been created in the Smartrr admin, *(see above article link)*, you can add the Smartrr bundle builder button to your shop by taking the following steps:&#x20;

1. In Smartrr's admin, navigate to Subscription Programs > **Bundles**
2. Click **Manage**
3. **Save** the bundle to the theme (or a duplicate theme) that you want the bundle builder button to appear on&#x20;

<figure><img src="https://3658670565-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FndNAuxS4koYyI8AQTpS9%2Fuploads%2FMZOdlt77CnpBZoIK0ZxF%2Fmanage-bundle.png?alt=media&#x26;token=bd173c59-0084-4b9d-9884-45f8cc92eaae" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3658670565-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FndNAuxS4koYyI8AQTpS9%2Fuploads%2FEdOBqWpVm4Z1ftVLBOxW%2Fconfirm-theme.png?alt=media&#x26;token=4107ca19-bbde-4e5e-8e6d-e4c760ada5cb" alt=""><figcaption><p>Saving to a theme will inject a snippet into the theme's liquid code. </p></figcaption></figure>

{% hint style="info" %}
Tip: We recommend testing the bundle on a clean [<mark style="color:blue;">Dawn theme</mark>](https://themes.shopify.com/themes/dawn/styles/default) for your shop. This will allow you to preview information about the bundle builder and make it easier to compare end results with your desired custom bundle.

![](https://3658670565-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FndNAuxS4koYyI8AQTpS9%2Fuploads%2FaxEWhOnpH6ijuWKFifNC%2FScreenshot%202022-12-05%20at%2017.03.06.png?alt=media\&token=83f5e07f-90d3-4c8e-a213-c1b9ff160914)
{% endhint %}

### Liquid Customizations & Custom Bundles

In the Shopify theme that the bundle has been saved to, click the **"more options" icon** left of the Customize button, click **Edit code** and search for snippets that begin with <mark style="color:orange;">`smartrr-bundle-`</mark>.&#x20;

<figure><img src="https://3658670565-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FndNAuxS4koYyI8AQTpS9%2Fuploads%2FyU7byBeYJ6gGGNUvsKJ1%2Fsmartrr-bundle.gif?alt=media&#x26;token=a127823d-61e8-4c73-8c85-fab3f1a51d4a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3658670565-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FndNAuxS4koYyI8AQTpS9%2Fuploads%2Ft8b98SKyw6zsG7ZOEKbW%2Fliquid.png?alt=media&#x26;token=79b49f9c-08c0-4492-84fa-aa8a105df6d8" alt=""><figcaption></figcaption></figure>

In the example above, we've created the bundle **All In Cheese and Fruit Bundle** in Smartrr. The corresponding file <mark style="color:orange;">`smartrr-bundle-all-in-cheese-and-fruit-bundle.liquid`</mark> has been injected into the theme's code. This file contains information about the bundle's name and slug, both of which need to be sent to the cart.&#x20;

{% hint style="info" %}
**Tip:** To manually render on any existing page, add `{% render 'smartrr-bundle-`<mark style="color:orange;">`{bundle-name}`</mark>`' %}` to that page's liquid template.&#x20;

Next, add the following code at the end of \<body> in theme.liquid:&#x20;

<pre class="language-html"><code class="lang-html">  &#x3C;!-- END SMARTRR RENDER SNIPPET -->
  {% render 'smartrr-bundle-modal', smartrr_default_page_url: '<a data-footnote-ref href="#user-content-fn-1">/pages/smartrr-bundle</a>' %}
  {% render 'smartrr-bundle-css' %}
  &#x3C;!-- BEGIN SMARTRR RENDER SNIPPET -->
</code></pre>

\
Be sure to change the page URL (ex.`/pages/bundle`) to the page where you have rendered the bundle. \
\
Prior to that you need to create a liquid file and a page in the Online Store. \
&#x20;  First head to the 'Edit Code' for the theme you are using. In the 'Templates' section create a new liquid file, using 'Page' as a template and '.liquid' as a file extension.  Add the code described in the 'Tip' section to that page. \
&#x20;  Head to the Shopify admin, click on the 'Online store' navigation button, then click on 'Pages'. Create a new page and use the 'page.{bundle-name}.liquid' file as a 'Theme template'.

Finally, add in the CTA button code that will trigger the bundle to open with the code:&#x20;

```
<div data-smartrr-modal-cta>
  <span>Build Your Box</span>
</div>
```

{% endhint %}

<figure><img src="https://3658670565-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FndNAuxS4koYyI8AQTpS9%2Fuploads%2FLbLQuw1hKgzIF6UxH58b%2FScreenshot%202022-12-05%20at%2016.59.32.png?alt=media&#x26;token=3620a9e1-f17f-4f5a-8709-92bb5bd81e61" alt=""><figcaption><p>When <code>smartrr-bundle-{bundle-name}.liquid</code> is rendered on the page, you will see the default bundle builder UI.</p></figcaption></figure>

Add a test bundle to your cart in your theme. View `/cart.json` after adding to view the line item properties that have been added.

{% hint style="info" %}
**Tip:** The recommended function for adding to cart is: `addBundleToCartAndRedirect` in `smartrr-bundle-js.liquid`.
{% endhint %}

<figure><img src="https://3658670565-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FndNAuxS4koYyI8AQTpS9%2Fuploads%2FlJw2E5Vfgx3JKPWm49Gn%2FScreenshot%202022-12-05%20at%2017.09.26.png?alt=media&#x26;token=1c8b3c7b-5e11-4578-9d5b-b20b56c92cbe" alt=""><figcaption></figcaption></figure>

#### Line Item Properties

Below are the line item properties that will be added to a given bundle product: &#x20;

```json
{
  "properties": {
    "Bundle": "Name of Bundle",
    "Product1": 4,
    "Product2": 2,
    "ProductN": "Number: Quantity",
    "_smartrr_info": "JSON String: Information about the Bundle"
  } 
}
```

Below are the line item properties from the example above, **All In Cheese and Fruit Bundle**.&#x20;

{% code overflow="wrap" %}

```json
{
  "properties": {
    "Bundle": "All In Cheese And Fruit Bundle",
    "Brie's Fine Cheese": 1,
    "Ben's Cheese": 1,
    "Juicy Apricots": 1,
    "Red Grapes": 1,
    "_smartrr_info": "{\"items\":[{\"id\":41346996043967,\"quantity\":1,\"selling_plan\":\"2153971903\"},{\"id\":41300866465983,\"quantity\":1,\"selling_plan\":\"2153971903\"},{\"id\":41925668634815,\"quantity\":1,\"selling_plan\":\"2153971903\"},{\"id\":41925668470975,\"quantity\":1,\"selling_plan\":\"2153971903\"}],\"date\":1670278109299,\"page\":\"https://briescheese.myshopify.com/\",\"bundle\":{\"name\":\"All In Cheese And Fruit Bundle\",\"slug\":\"all-in-cheese-and-fruit-bundle/777cdce8-451d-41d8-9fe4-136c969fa7c0\"}}"
  } 
}
```

{% endcode %}

{% hint style="info" %}
**Note:** `_smartrr_info` is stringified JSON. If you're using a JS object to store these line item properties then be sure to use JSON.stringify when adding this information to cart item properties.
{% endhint %}

When the JSON is parsed, you'll see:&#x20;

```json
{
   "items":[
      {
         "id":41346996043967,
         "quantity":1,
         "selling_plan":"2153971903"
      }{
         "id":41300866465983,
         "quantity":1,
         "selling_plan":"2153971903"
      }{
         "id":41925668634815,
         "quantity":1,
         "selling_plan":"2153971903"
      }{
         "id":41925668470975,
         "quantity":1,
         "selling_plan":"2153971903"
      }
   ],
   "date":1670278109299,
   "page":"https://briescheese.myshopify.com",
   "bundle":{
      "name":"All In Cheese And Fruit Bundle",
      "slug":"all-in-cheese-and-fruit-bundle/777cdce8-451d-41d8-9fe4-136c969fa7c0"
   }
}
```

If a bundle purchase is one-time and not a subscription, `"selling_plan"` will be omitted. Example:&#x20;

```json
{
   "items":[
      {
         "id":41346996043967,
         "quantity":1
      }{
         "id":41300866465983,
         "quantity":1
      }{
         "id":41925668634815,
         "quantity":1
      }{
         "id":41925668470975,
         "quantity":1
      }
   ],
   "date":1670278109299,
   "page":"https://briescheese.myshopify.com",
   "bundle":{
      "name":"All In Cheese And Fruit Bundle",
      "slug":"all-in-cheese-and-fruit-bundle/777cdce8-451d-41d8-9fe4-136c969fa7c0"
   }
}
```

Below is a plain-text schema of the parsed JSON:&#x20;

```json
{
   "Array:items":[
      {
         "id":"Number: Variant Id",
         "quantity":"Number: Quantity",
         "selling_plan":"String/Number: Selling Plan ID"
      }
   ],
   "date":"Number: Time of purchase",
   "page":"URLString: Page of purchase",
   "Object:bundle":{
      "name":"String: Name of Bundle",
      "slug":"String: Unique Slug of Bundle"
   }
}
```

Below is the JSON schema that can be used for reference:&#x20;

```json
{
   "$schema":"http://json-schema.org/draft-04/schema#",
   "type":"object",
   "properties":{
      "items":{
         "type":"array",
         "items":[
            {
               "type":"object",
               "properties":{
                  "id":{
                     "type":"integer"
                  },
                  "quantity":{
                     "type":"integer"
                  },
                  "selling_plan":{
                     "type":"integer"
                  }
               },
               "required":[
                  "id",
                  "quantity",
                  "selling_plan"
               ]
            }
         ]
      },
      "date":{
         "type":"integer"
      },
      "page":{
         "type":"string"
      },
      "bundle":{
         "type":"object",
         "properties":{
            "name":{
               "type":"string"
            },
            "slug":{
               "type":"string"
            }
         },
         "required":[
            "name",
            "slug"
         ]
      }
   },
   "required":[
      "items",
      "date",
      "page",
      "bundle"
   ]
}
```

Use these line item properties to integrate with any existing 3PL setup to ensure your bundle contains the correct products.&#x20;

Below is the code for generating line properties( see function `addBundleToCartAndRedirect` in `smartrr-bundle-js.liquid`)

```javascript
var bundleInfo = {
  items: [],
  date: new Date().getTime(),
  page: window.location.toString(),
  bundle: {
    name: bundle.name,
    slug: bundle.slug,
  },
};
...;
/* For each item in bundle */
bundleInfo.items.push({
  id: lineItem.variant.id,
  quantity: lineItem.quantity,
  selling_plan: sellingPlan,
});
properties[lineItem.product.title] = lineItem.quantity;
/* End For Each */
...;
properties["Bundle"] = bundle.name;
properties["_smartrr_info"] = JSON.stringify(bundleInfo);
```

[^1]: Change this text to be your desired url
