> ## Documentation Index
> Fetch the complete documentation index at: https://partner-docs.foxsell.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi Variant Bundles

> Metafields and Metaobject Structure for Multi Variant Bundles

<Tabs>
  <Tab title="Structure">
    <ResponseField name="multi_variant_bundled_variants" type="Metaobject">
      Multi Variant Bundle Configuration Metaobject

      <Expandable title="fields" defaultOpen>
        <ResponseField name="variant_properties" type="list of variants" required>
          List of variant properties containing information about each variant in the bundle

          <Expandable title="format">
            <ResponseField name="variant_id" type="string" required>
              Variant ID (without GID prefix)
              <Note>Example: `12345678`</Note>
            </ResponseField>

            <ResponseField name="quantity" type="number" required>
              Quantity of this variant included in the bundle
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="variants" type="list of variant references" required>
          List of variant references included in this bundle variant
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Tab>

  <Tab title="Liquid Section">
    <Tip>
      Add this snippet as a section in your theme to see the values of the metafield.
      This metafield is attached to each **variant**, not the product.

      **Note**: The `namespace` and `key` are constant for all stores
    </Tip>

    ```liquid theme={null}
    {% liquid
      assign app_namespace = 'app--67872686081'
      assign current_variant = product.selected_or_first_available_variant

      assign multi_variant_bundle_config = current_variant.metafields[app_namespace].multi_variant_bundled_variants.value
    %}

    {% if multi_variant_bundle_config %}
      {% liquid
        assign variant_properties = multi_variant_bundle_config.variant_properties.value
        assign bundled_variants = multi_variant_bundle_config.variants.value
      %}

      <p><strong>Bundle Configuration for Variant: {{ current_variant.title }}</strong></p>

      <p><strong>Variant Properties</strong></p>
      {{ variant_properties | json }}

      <p><strong>Bundled Variants:</strong></p>
      {% for variant_prop in variant_properties %}
        {% assign variant_id = variant_prop.variant_id | times: 1 %}
        {% assign variant = bundled_variants | where: 'id', variant_id | first %}
        
        {% if variant %}
          <div style="border: 1px solid #ccc; padding: 10px; margin: 10px 0;">
            <p><strong>Variant Title:</strong> {{ variant.title }}</p>
            <p><strong>Variant ID:</strong> {{ variant_prop.variant_id }}</p>
            <p><strong>Product Title:</strong> {{ variant.product.title }}</p>
            <p><strong>Price:</strong> {{ variant.price | money }}</p>
            <p><strong>Quantity in Bundle:</strong> {{ variant_prop.quantity }}</p>
          </div>
        {% endif %}
      {% endfor %}
    {% else %}
      <p>This variant does not have a multi-variant bundle configuration.</p>
    {% endif %}

    {% schema %}
    {
      "name": "FoxSell Multi Variant Bundle Test",
      "settings": [],
      "presets": [
        {
          "name": "FoxSell Multi Variant Bundle Test"
        }
      ]
    }
    {% endschema %}
    ```
  </Tab>

  <Tab title="Variant Selector">
    <Tip>
      Add this snippet to your product page to show bundle contents when variant changes
    </Tip>

    ```liquid theme={null}
    {% liquid
      assign app_namespace = 'app--67872686081'
    %}

    <div id="bundle-contents">
      <!-- Bundle contents will be displayed here -->
    </div>

    <script>
      document.addEventListener('DOMContentLoaded', function() {
        const productJson = {{ product | json }};
        const appNamespace = '{{ app_namespace }}';
        
        // Function to display bundle contents for a variant
        function displayBundleContents(variantId) {
          const variant = productJson.variants.find(v => v.id === variantId);
          if (!variant) return;

          const bundleConfig = variant.metafields?.[appNamespace]?.multi_variant_bundled_variants?.value;
          if (!bundleConfig) {
            document.getElementById('bundle-contents').innerHTML = '<p>No bundle configuration for this variant.</p>';
            return;
          }

          const variantProperties = bundleConfig.variant_properties.value;
          const bundledVariants = bundleConfig.variants.value;

          let html = '<div class="bundle-contents"><h3>This bundle includes:</h3><ul>';
          
          variantProperties.forEach(variantProp => {
            const bundledVariant = bundledVariants.find(v => v.id == variantProp.variant_id);
            
            if (bundledVariant) {
              html += `<li>
                <strong>${bundledVariant.product.title}</strong> - ${bundledVariant.title}
                (Quantity: ${variantProp.quantity})
              </li>`;
            }
          });
          
          html += '</ul></div>';
          document.getElementById('bundle-contents').innerHTML = html;
        }

        // Display bundle contents for initially selected variant
        displayBundleContents({{ product.selected_or_first_available_variant.id }});

        // Update bundle contents when variant changes
        document.addEventListener('variant:change', function(event) {
          displayBundleContents(event.detail.variant.id);
        });
      });
    </script>
    ```
  </Tab>

  <Tab title="FoxSell JS Object">
    <Tip>
      Add this snippet in your `liquid` file to access bundle config via `window.foxsell` object.

      This creates a bundle config object for each **variant**.

      **Note**: The `namespace` and `key` are constant for all stores
    </Tip>

    ```liquid theme={null}
    {% liquid
      assign app_namespace = 'app--67872686081'
    %}

    <script>
      window.foxsell = window.foxsell || {};
      window.foxsell.variantBundles = {};

      {% for variant in product.variants %}
        {% liquid
          assign multi_variant_bundle_config = variant.metafields[app_namespace].multi_variant_bundled_variants.value
        %}

        {% if multi_variant_bundle_config %}
          {% liquid
            assign variant_properties = multi_variant_bundle_config.variant_properties.value
            assign bundled_variants = multi_variant_bundle_config.variants.value
          %}

          window.foxsell.variantBundles['{{ variant.id }}'] = {
            variantId: '{{ variant.id }}',
            variantTitle: '{{ variant.title }}',
            bundledVariants: {{ bundled_variants | json }},
            variantProperties: {{ variant_properties | json }}
          };
        {% endif %}
      {% endfor %}

      // Helper function to get bundle config for current variant
      window.foxsell.getBundleForVariant = function(variantId) {
        return window.foxsell.variantBundles[variantId] || null;
      };
    </script>
    ```
  </Tab>

  <Tab title="Storefront API">
    <Tip>
      Use the Shopify Storefront API to query the metafields namespace containing your bundle configuration.

      This metafield is on the **variant**, not the product.

      **Note**: The `namespace` and `key` are constant for all stores
    </Tip>

    ```graphql theme={null}
    fragment ProductVariant on ProductVariant {
      id
      title
      price {
        amount
        currencyCode
      }
      multi_variant_bundled_variants: metafield(
        namespace: "app--67872686081"
        key: "multi_variant_bundled_variants"
      ) {
        id
        namespace
        key
        value
        type
        reference {
          ... on Metaobject {
            id
            handle
            type
            fields {
              key
              type
              value
              references(first: 100) {
                nodes {
                  ... on ProductVariant {
                    id
                    title
                    price {
                      amount
                      currencyCode
                    }
                    product {
                      id
                      title
                      handle
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    # Query to get product with all variants and their bundle configs
    query GetProductWithVariantBundles($handle: String!) {
      product(handle: $handle) {
        id
        title
        handle
        variants(first: 100) {
          nodes {
            ...ProductVariant
          }
        }
      }
    }
    ```
  </Tab>
</Tabs>
