Fix dynamic bundles displaying incorrectly in the cart

When using bundles, a single product is typically added to the cart, along with its title, image, price, and contents.

However, dynamically priced bundles behave differently. Instead of adding one bundle product, the system adds the individual products to the cart so the total price can be calculated dynamically.

This can create two issues:

  • Customers can edit individual item quantities, which may conflict with bundle rules
  • Bundle items lose their grouped presentation and appear as separate products in the cart

To resolve this, you can use custom Liquid code to group bundle items and display them as a single product in the cart.


Before you start

These instructions require custom coding. Custom code is not supported by Recharge per the design and integration policy. Consider working with a developer or Recharge Partner Agency.


Install snippets manually when auto-install fails

Recharge automatically installs two snippets by detecting where cart.items is used in your theme.

However, automatic installation can fail if your theme:

  • Uses a non-standard cart rendering method
  • Has heavily customized cart logic
  • Does not use Liquid to render cart items (for example, uses Jinja or another templating language)

In these cases, you must install the snippets manually. After installation:

  • The dynamic bundle appears as a single item in the cart
  • Customers cannot edit individual bundle item quantities from the cart
  • Bundle contents display as a grouped product

Step 1 - Duplicate your theme

Before making changes:

  1. In Shopify, go to Online Store and select Themes
  2. Locate your theme
  3. Click Actions and select Duplicate
  4. Open the duplicated theme and click Edit code

Step 2 - Locate your cart file

Find the file responsible for rendering cart items. Common filenames include:

  • main-cart-items.liquid
  • cart.liquid

Step 3 - Identify the cart items loop

Locate the loop that renders cart items. It typically looks like:

{%- for item in cart.items -%}

Step 4 - Add bundle detection logic

Paste the following code before the cart items loop:

{%- assign rc_displayed_bundles = '' -%}
{%- assign rc_bundles = '' -%}
{%- for recharge_cart_item in cart.items -%}
  {%- if recharge_cart_item.properties._rc_bundle -%}
    {%- unless rc_bundles contains recharge_cart_item.properties._rc_bundle -%}
      {%- assign rc_bundles = rc_bundles | append: ',' | append: recharge_cart_item.properties._rc_bundle -%}
    {%- endunless -%}
  {%- endif -%}
{%- endfor -%}
{%- assign rc_bundles = rc_bundles | remove_first: ',' -%}

Step 5 - Render bundle items

Paste the following code inside the cart items loop, immediately after the opening tag:

{%- assign rc_bundle_id = item.properties["_rc_bundle"] -%}
{%- if rc_bundles contains item.properties._rc_bundle -%}
  {%- unless rc_displayed_bundles contains item.properties._rc_bundle -%}
    {%- assign rc_bundle_price = 0 -%}
    {%- assign rc_bundle_original_price = 0 -%}
    {%- assign rc_selling_plan_name = '' %}
    {%- assign rc_bundle_product = '' -%}
    {%- assign rc_bundle_contents = '' -%}
    {%- assign rc_bundle_handle = '' -%}
    {%- assign rc_bundle_url_to_remove = '/cart/update?' -%}
    {%- assign rc_bundle_variant = '' -%}
    {%- assign rc_bundle_variant_id = '' -%}
    {%- for item in cart.items -%}
      {%- if item.properties["_rc_bundle"] == rc_bundle_id -%}
        {%- assign rc_bundle_price = rc_bundle_price | plus: item.final_line_price -%}
        {%- assign rc_bundle_original_price = rc_bundle_original_price | plus: item.original_line_price -%}
        {%- assign rc_bundle_contents = rc_bundle_contents | append: ', ' | append: item.quantity | append: 'x ' | append: item.title -%}
        {%- if rc_selling_plan_name.size == 0 -%}
          {%- assign rc_selling_plan_name = item.selling_plan_allocation.selling_plan.name -%}
        {%- endif -%}  
        {%- assign rc_bundle_handle = item.properties._rc_bundle_parent -%}
        {%- assign rc_bundle_variant_id = item.properties._rc_bundle_variant | plus: 0 -%}
        {%- assign rc_bundle_url_to_remove = rc_bundle_url_to_remove | append: 'updates[' | append: item.key | append: ']=0&' -%}
      {%- endif -%}
    {%- endfor -%}
    {%- assign rc_bundle_product = all_products[rc_bundle_handle] -%}
    {%- assign rc_bundle_contents = rc_bundle_contents | remove_first: ', ' -%}
    {%- assign rc_displayed_bundles = rc_displayed_bundles | append: ',' | append: item.properties._rc_bundle -%}
    {%- for variant in rc_bundle_product.variants -%}
      {%- if variant.id == rc_bundle_variant_id -%}
        {%- assign rc_bundle_variant = variant -%}
      {%- endif -%}
    {%- endfor -%}
    {%- comment -%}
      Render bundle item
    {%- endcomment -%}
    <style>
      .rc-bundle-item {
        display: flex;
        align-items: flex-start;
        padding: 20px 0;
      } 
      .rc-bundle-image-wrapper {
        width: 150px;
        padding-right: 1rem;
      }
      .rc-bundle-image {
        max-width: 100%;
      }
      .rc-bundle-title {
        display: block;
        font-weight: bold;
      }
      .rc-bundle-variant,
      .rc-bundle-contents,
      .rc-bundle-price,
      .rc-bundle-frequency {
        display: block;
      }
      @media screen and (max-width: 749px) {
        .rc-bundle-image-wrapper {
          width: 33%;
        }
        .rc-bundle-content {
          width: 66%;
        }
      }
    </style>
    <tr>
      <td colspan="10">
        <div class="rc-bundle-item">
          <div class="rc-bundle-image-wrapper">
            <img class="rc-bundle-image" src="{{ rc_bundle_product.featured_image | image_url: width: 150 }}">
          </div>  
          <div class="rc-bundle-content">
            <span class="rc-bundle-title">{{ rc_bundle_product.title }}</span>
            {% if rc_bundle_product.variants.size > 1 %}
              <span class="rc-bundle-variant">{{ rc_bundle_variant.title }}</span>
            {% endif %}
            <span class="rc-bundle-contents">Contents: {{ rc_bundle_contents }}</span>
            <span class="rc-bundle-price">{{ rc_bundle_price | money }}</span>
            <span class="rc-bundle-frequency">{{ rc_selling_plan_name }}</span>
            <a href="{{ rc_bundle_url_to_remove }}">Remove</a>
          </div>  
        </div>
      </td>
    </tr>
    {%- comment -%}
      End render bundle item
    {%- endcomment -%}
  {%- endunless -%}
  {% continue %}
{%- endif -%}

Step 6 (Optional) - Customize the bundle item layout

If you want to further customize the bundle display to match the layout of other items in your cart, you can use the following Liquid variables to control how bundle information is rendered.

VariableDescriptionHow to use it
Bundle titleYour bundle product title{{ rc_bundle_product.title }}
Variant titleThe selected variant title{{ rc_bundle_variant.title }}
Bundle imageThe bundle product image{{ rc_bundle_product.featured_image | image_url: width: 300 }}
Contents listA comma-separated list of the product names in the bundle contents{{ rc_bundle_contents }}
Bundle priceThe total price of all items in the bundle, including any line-level discounts{{ rc_bundle_price | money }}
Original bundle priceThe original bundle price before discounts{{ rc_bundle_original_price | money }}
Selling plan nameThe selling plan name (for example, Delivery every 1 week){{ rc_selling_plan_name }}
Remove URLA URL to remove the bundle from the cart, similar to line_item.url_to_remove{{ rc_bundle_url_to_remove }}

Example

<style>
  .rc-bundle-item {
    display: flex;
    align-items: flex-start;
    padding: 20px 0;
  }

  .rc-bundle-image-wrapper {
    width: 150px;
    padding-right: 1rem;
  }

  .rc-bundle-image {
    max-width: 100%;
  }

  .rc-bundle-title {
    display: block;
    font-weight: bold;
  }

  .rc-bundle-variant,
  .rc-bundle-contents,
  .rc-bundle-price,
  .rc-bundle-frequency {
    display: block;
  }

  @media screen and (max-width: 749px) {
    .rc-bundle-image-wrapper {
      width: 33%;
    }

    .rc-bundle-content {
      width: 66%;
    }
  }
</style>

Customize the bundle layout

VariableDescription
{{ rc_bundle_product.title }}Bundle product title
{{ rc_bundle_variant.title }}Selected variant title
{{ rc_bundle_product.featured_image | image_url: width: 300 }}Bundle image
{{ rc_bundle_contents }}Bundle contents
{{ rc_bundle_price | money }}Total bundle price
{{ rc_bundle_original_price | money }}Original price
{{ rc_selling_plan_name }}Selling plan
{{ rc_bundle_url_to_remove }}Remove URL

Step 7 - Publish your duplicated theme

  1. Preview your duplicated theme
  2. Confirm the bundle displays as a single item
  3. Confirm customers cannot edit individual items
  4. Publish your theme when ready