# Dynamic Bundle Products

The Dynamic bundle products feature allows the customer to select products that they want in a bundle.

## Enabling the Feature

The dynamic bundle products becomes available when you include its template in your theme and the product is a type dyanmic bundle you can create one from the products and and choose `Dynamic bundle`.

**Path:** `https://dashboard.zid.sa/en-sa/stores/<store_id>/catalog/products`


### How to Enable

To enable the dynamic bundle products section in your theme, include the following template:

```jinja
{% if product.product_class == 'dynamic_bundle' %}
    {% include 'vitrin:products/bundle-products.jinja' %}
{% endif %}
```

**Best Practice:**
It is mandatory to add the dynamic bundle primarily on the Product Details Page (PDP), where the full product context and the `product_class` is available.

----

## Theme Usage Example:

```javascript
  window.addEventListener('vitrin:bundle-selections:updated', function(event) {
    const cartData = event?.detail?.data;
    const bundlePayload = cartData?.cartPayload;
    const isValid = cartData?.isSelectionsValid;

    // Store the bundle payload globally so productAddToCart can use it
    window.bundleCartPayload = bundlePayload;

    // cart button is initially disabled until bundle selections are valid
    const buyNowButton = $('.btn-buy-now');
    const addToCartBtn = document.querySelector('.btn-add-to-cart');


    if (addToCartBtn) {
        if (!isValid) {
            addToCartBtn.classList.add('disabled');
            addToCartBtn.disabled = true;
            buyNowButton.prop('disabled', true);
        } else {
            addToCartBtn.classList.remove('disabled');
            addToCartBtn.disabled = false;
            buyNowButton.disabled = false;
            buyNowButton.prop('disabled', false);
        }
    }
});
```

:red_circle: **Important:** The `vitrin:bundle-selections:updated` event will get trigger every time the customer change the selected product bundle so you will get the values of the selected bundle products and you need to store it for later because you will need to send it to the add product api -- [Please refer add product guide for theme developers.](https://docs.zid.sa/cart-1475306m0#add-product)

#### **Example on how to add selected bundle product to cart**

```js
const addProductOptions = bundlePayload
  ? { ...window.bundleCartPayload, form_id: "product-form" }
  : { form_id: "product-form" };

window.zid.cart
  .addProduct(addProductOptions, {
    showErrorNotification: true,
  })
  .then(function (response) {
        // on success
  })
  .catch(function (error) {
        // On error
  });

```


## Custom Styles Integration

The Checkout Popup supports the Zid Custom Styles system. You can override specific styles in a safe, isolated way without affecting other dialogs.

### How to Use Custom Styles

```javascript
window.zidCustomStyles = {
  bundle_selection: {
    '.dynamic-bundle-selection-groups': {
      borderRadius: '16px',
      padding: '14px 28px',
      fontWeight: '600',
    },
    '.dynamic-bundle-group-accordion': {
      fontSize: '22px',
      fontWeight: '700',
    },
    '.multiple-selection': {
      margin: '12px 0',
    },
    '.regular-selection': {
      border: '1px solid #E0E0E0',
    },
    '.dynamic-bundle-group-header': {
        fontSize: '20px',
    },
    '.dynamic-bundle-group-progress': {
      fontWeight: '600',
      color: 'gray'
    },
    '.dynamic-bundle-group-counter': {
      fontWeight: '600',
      color: 'gray'
    },
    '.dynamic-bundle-group-counter': {
      borderRadius: '16px',
    },
    '.dynamic-bundle-slot-items': {
      backgroundColor: '#F9F9F9',
    },
    '.dynamic-bundle-item': {
      borderRadius: '16px',
    },
    '.dynamic-bundle-item-content': {
      fontSize: '18px',
    },
    '.dynamic-bundle-item-info': {
      fontWeight: '600',
    },
    '.dynamic-bundle-item-details': {
      border: '1px solid #E0E0E0',
    },
    '.dynamic-bundle-item-image': {
      color: 'gray'
    },
    '.dynamic-bundle-item-options': {
      fontWeight: '600',
    },
    '.dynamic-bundle-item-option-group': {
      borderRadius: '8px',
    },
    '.dynamic-bundle-item-option-choices': {
      color: 'neutral'
    },
  },
};
```

The component key for the checkout popup is **`bundle_selection`**.


To understand the complete flow of the Custom Styles system — including structure, validation, and advanced usage — [please refer to the Custom Styles Guide for Theme Developers.](https://docs.zid.sa/custom-styles-guide-1702191m0)

---

## Best Practices

* Include the template in product details page.
* Always use **optional chaining** when interacting with the API.
* Add event listener to `vitrin:bundle-selections:updated` event so you can recevie the selected customer bundler.

## Events Reference Summary

| Events                             | Description              |
| ---------------------------------- | ------------------------ |
| `vitrin:bundle-selections:updated` | This event is triggered on every change made by the customer within the dynamic bundle. |



## Summary

- Allows customers to create and customize their own product bundles by selecting items dynamically.
- Becomes available when the product type is set to Dynamic Bundle and the bundle template is included in the PDP.
- Emits the `vitrin:bundle-selections:updated` event on every customer selection change.
- Requires storing the emitted bundle payload and sending it with the add-to-cart request.
- Supports Zid Custom Styles for safe and isolated UI customization.

