Skip to main content

Default Bundle Template

The main Liquid template file for rendering bundle sections. The template handles two layout types (bundle and bundle_component) and includes loading skeleton states, product cards with variant selectors, pricing, and add-to-cart functionality.

Template Structure

The template is organized into these key sections:
  1. Layout detection — assigns the correct settings based on config.layout
  2. Bundle component header — collapsible header for the bundle_component layout
  3. Loading skeleton — placeholder UI shown while bundle data loads
  4. Product cards — image, title, price, variant/option selectors for each product
  5. Pricing and ATC — total price display and add-to-cart container (component layout only)
{% assign productComponentTitle = template.translations.productComponentTitle | replace: "{{count}}", bundle.images.length %}

{% if config.layout == 'bundle_component' %}
  {% assign setting = template.settings.bundleComponent %}
{% else %}
  {% assign setting = template.settings.bundle %}
{% endif %}

{% if config.layout == 'bundle_component' %}
  <div class='rk-b-c-head'>
    <div class='rk-b-c-h-title'>
      <svg width="23" height="25" viewBox="0 0 23 25" fill="none" xmlns="http://www.w3.org/2000/svg">
      <g clip-path="url(#clip0_2869_1890)">
      <path fill-rule="evenodd" clip-rule="evenodd" d="M0.163574 15.9316L11.2747 21.9316L22.3858 15.9316V18.9316L11.2747 24.9316L0.163574 18.9316V15.9316ZM0.163574 9.93164L11.2747 15.9316L22.3858 9.93164V12.9316L11.2747 18.9316L0.163574 12.9316V9.93164ZM11.2747 0.931641L22.3858 6.93164L11.2747 12.9316L0.163574 6.93164L11.2747 0.931641Z" fill="black"/>
      </g>
      <defs>
      <clipPath id="clip0_2869_1890">
      <rect width="22.2222" height="24" fill="white" transform="translate(0.163574 0.931641)"/>
      </clipPath>
      </defs>
      </svg>
        <span>{{ template.translations.productComponentTitle | replace: '{{count}}', bundle.productComponents.length }}</span>
        </div>
        <svg class="rk-b-c-cheveron" width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path d="M5.2959 15.9316L12.2959 8.93164L19.2959 15.9316" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </div>
{% endif %}
<div data-rk-bundle-id="{{ bundle.id }}" class="rk-bundle-card">
{% if loading %}
  {% if bundle.optionsType == "product" and bundle.bundleType == "custom" %}
    <span class="rk-total-product">
      {% if config.layout == "bundle" %}
        {{ template.translations.bundleSectionTitle | replace: "{{count}}", bundle.productComponents.length }}
      {% endif %}
      {% if config.layout == "bundle_component" %}
        {{ bundle.title }}
      {% endif %}
    </span>
    <div class="rk-bundle-container rk-bundle-{{ bundle.id }}-holder">
      {% for component in bundle.productComponents %}
        <div class="rk-p-c-container" data-rk-bundle-component-id="{{ product.id }}">
          <div class="rk-p-c-product-image-container">
            <img
              class="rk-p-c-product-image rk-image-{{ product.id }}"
              {% if image contains '?' %}
                src="{{ component.image }}&width={{ setting.productCard.image.width | default: 110 }} }}&height={{ setting.productCard.image.height | default: 133 }} }}&crop=center&pad_color=121212"
              {% else %}
                src="{{ component.image }}?width={{ setting.productCard.image.width | default: 110 }} }}&height={{ setting.productCard.image.height | default: 133 }} }}&crop=center&pad_color=121212"
              {% endif %}
              alt="{{ component.image }} image" />
          </div>
          <div class="rk-p-c-product-details">
            <div class="rk-p-c-head">
              <div class="product-title-skeleton skeleton"></div>
              <div class="product-price-skeleton skeleton"></div>
            </div>
            <div class="rk-p-c-footer">
              <div class="selector-skeleton skeleton"></div>
            </div>
          </div>
        </div>
        {% if forloop.index < products.size %}
          <span class="rk-plus" id="rk-plus-{{ forloop.index }}">+</span>
        {% endif %}
      {% endfor %}
    </div>
  {% endif %}
{% else %}
  {% if bundle.optionsType == "product" and bundle.bundleType == "custom" %}
    <div class='rk-bundle-head'>
      <span class="rk-total-product">
        {% if config.layout == "bundle" %}
          {{ template.translations.bundleSectionTitle | replace: "{{count}}", components.length }}
        {% endif %}
        {% if config.layout == "bundle_component" %}
            {{ bundle.title }}
        {% endif %}
      </span>
      <div style="display: flex; align-items: center; justify-content: center">
        {% if bundle.data.discountConfig.bundleDiscount %}
          <span class='rk-discount'>
            {{ template.translations.discountLabelText | replace: "{{percent}}", bundle.data.discountConfig.bundleDiscount }}
          </span>
        {% endif %}
      </div>
    </div>
    <div class="rk-bundle-container rk-bundle-{{ bundle.id }}-holder">
      {% for product in components %}
      {% assign productIndex = forloop.index0 %}
        <div class="rk-p-c-container" data-rk-bundle-component-id="{{ product.id }}">
          {% if product.image %}
            <div class="rk-p-c-product-image-container">
              <img
                class="rk-p-c-product-image rk-image-{{ product.id }}"
                {% if product.image contains '?' %}
                  src="{{ product.image }}&width={{ setting.productCard.image.width | default: 110 }} }}&height={{ setting.productCard.image.height | default: 133 }} }}&crop=center&pad_color=121212"
                {% else %}
                  src="{{ product.image }}?width={{ setting.productCard.image.width | default: 110 }} }}&height={{ setting.productCard.image.height | default: 133 }} }}&crop=center&pad_color=121212"
                {% endif %}
                alt="{{ product.title }} image" />
            </div>
          {% endif %}
          <div class="rk-p-c-product-details">
            <div class="rk-p-c-head">
                <a href="/products/{{ product.handle }}?pr_ref_pid={{ bundle.id }}&pr_rec_id={{ product.id }}&pr_prod_strat=glood_bundle&pr_seq={% if config.layout == 'bundle_component'%}component_selector{% else %}bundle{% endif %}">
                  <span class='rk-bundle-comp-title {% if setting.productCard.title.multipleLines == false %} rk-truncate-title {% endif %}'>
                      {{ product.title }}
                  </span>
                </a>
              <span class='rk-product-price rk-price-{{ product.id }}'>{{ product.price }}</span>
            </div>
            <div class="rk-p-c-footer">
              {% if setting.showProductOptions == true %}
                  <div class="rk-options-selector-{{ product.id }} rk-p-options-selector">
                  {% for pOption in product.productOptions %}
                  <div class="rk-option-selector-wrapper">
                    <span class="rk-option-name">
                      {{ pOption.name }}
                    </span>
                    <radiogroup data-option-index="{{ forloop.index0 }}" data-option-name="{{ pOption.name }}" data-option-type="{{ pOption.name | downcase }}">
                      {% assign idx = forloop.index0 %}
                      {% for value in pOption.values %}
                      <input data-component-index="{{productIndex}}" data-option-name="{{ pOption.name }}" data-option-index="{{ idx }}" name="{{product.id}}_option_{{ idx }}" value="{{ value }}" data-product-id="{{ product.id }}" type="radio" id="rk_{{ product.id }}_{{ pOption.name }}_{{ value | replace: ' ', '_' }}">
                      <label for="rk_{{ product.id }}_{{ pOption.name }}_{{ value | replace: ' ', '_' }}">
                        <div class="rk-option-select_wrapper">
                          <span class="rk-option-select__title">
                            {{ value }}
                          </span>
                        </div>
                      </label>
                      {% endfor %}
                    </radiogroup>
                    </div>
                  {% endfor %}
                    </div>
              {% endif %}
              {% if product.variants.length > 1%}
                <select class="rk-p-c-variant-selector rk-variant-selector-{{ product.id }}">
                  {% for variant in product.variants %}
                    <option value="{{ variant.value }}" {% unless variant.available %}disabled{% endunless %}>
                      {{ variant.value }}
                    </option>
                  {% endfor %}
                </select>
              {% endif %}
            </div>
          </div>
        </div>
        {% if forloop.index < products.size %}
          <span class="rk-plus" id="rk-plus-{{ forloop.index }}">+</span>
        {% endif %}
      {% endfor %}
      {% if config.layout == "bundle_component" %}
        <div class="rk-atc-container">
          <div class="rk-price">
            <span class="rk-{{ bundle.id }}-total-price rk-total-price"></span>
            <span class="rk-cmp-price">
              <strike class="rk-cmp-p-text"></strike>
            </span>
            {% if bundle.data.discountConfig.bundleDiscount %}
              <span class="rk-p-d-text">
                {{ template.translations.bundleDiscount | replace: "{{percent}}", bundle.data.discountConfig.bundleDiscount }}
              </span>
            {% endif %}
          </div>
          <div class="rk-bundle-atc-container"></div>
        </div>
      {% endif %}
    </div>
  {% endif %}
  {% endif %}
</div>