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

# Hooks

> Complete guide to bundle hooks in Glood.AI

# Bundle Hooks

Bundle hooks let you customize the behavior of Glood.AI bundles at key lifecycle points. There are five hooks available, each called at a specific stage of the bundle's lifecycle.

## Hook Lifecycle Flow

### 1. Configuration Phase

* `OnConfigLoad` is called when bundle data is first loaded
  * Modify or enrich bundle configuration
  * Set up initial state

### 2. Rendering Phase

* `OnBundleRender` transforms bundle data for the Liquid template
  * Map products with options and variants
  * Calculate pricing
  * Resolve translations

### 3. Interaction Phase

* `OnVariantChange` handles variant selection changes
  * Update URL parameters
  * Trigger UI updates

### 4. Cart Operations Phase

* `OnAddToCart` fires before the cart API request
  * Validate cart operations
  * Pre-cart UI updates
* `OnAddedToCart` fires after successful cart addition
  * Post-cart confirmations
  * Analytics tracking

## Available Hooks

### 1. OnConfigLoad

**Purpose:** Modify bundle data when it is first loaded, before any rendering occurs.

**Parameters:**

| Parameter | Type   | Description                                                                 |
| --------- | ------ | --------------------------------------------------------------------------- |
| `bundle`  | Object | The raw bundle data object containing products, variants, and configuration |
| `utils`   | Object | Utility functions (see [Available Utilities](#available-utilities))         |

**Returns:** The modified (or unmodified) bundle object.

**Example:**

```javascript theme={null}
OnConfigLoad: function OnConfigLoad(bundle, utils) {
    // Filter out-of-stock products
    bundle.products = bundle.products.filter(p => p.availableForSale);
    return bundle;
}
```

**Use Cases:**

* Filter products before rendering
* Enrich bundle data with additional information
* Override default configuration

***

### 2. OnBundleRender

**Purpose:** Transform raw bundle data into the format consumed by the Liquid template. This is the primary hook for controlling what gets rendered.

**Parameters:**

| Parameter | Type   | Description                                                                |
| --------- | ------ | -------------------------------------------------------------------------- |
| `bundle`  | Object | Bundle data with `products`, `variants`, `template`, and `data` properties |
| `utils`   | Object | Utility functions (see [Available Utilities](#available-utilities))        |
| `states`  | Object | Current UI state including `selectedProductOptions` array                  |

**Returns:** An object with `products` (array) and `translations` (object).

**Example:**

```javascript theme={null}
OnBundleRender: function OnBundleRender(bundle, utils, states) {
    const totalPrice = utils.currencyFormatter(
        bundle.products.reduce((acc, product) => {
            return acc + parseFloat(
                utils.getComponentPrice(product.id, states.selectedProductOptions, bundle)
            );
        }, 0)
    );

    const translations = utils.getTranslations({
        data: bundle,
        productsCount: utils.getTotalProductsInbundles(bundle),
        totalPrice,
    });

    const products = (bundle?.products ?? []).map((product) => ({
        title: product.title,
        options: [{
            name: 'Type',
            value: utils.getProductOptions(product.id, bundle)
                .map((option) => option.value)
                .join(', '),
        }],
        variants: utils.getProductOptions(product.id, bundle),
        image: product?.featuredImage?.url,
        handle: product.handle,
        id: product.id,
    }));

    return { products, translations };
}
```

**Use Cases:**

* Custom product mapping and data transformation
* Price calculation logic
* Custom translation resolution
* Adding computed fields to products

***

### 3. OnVariantChange

**Purpose:** Handle variant selection changes when a customer picks a different option.

**Parameters:**

| Parameter   | Type   | Description                                                         |
| ----------- | ------ | ------------------------------------------------------------------- |
| `variantId` | Number | The selected variant ID                                             |
| `utils`     | Object | Utility functions (see [Available Utilities](#available-utilities)) |

**Returns:** void

**Example:**

```javascript theme={null}
OnVariantChange: function OnVariantChange(variantId, utils) {
    // Update URL with selected variant
    const url = new URL(window.location);
    url.searchParams.set('variant', variantId);
    window.history.replaceState({}, '', url);

    // Custom tracking
    console.log('Variant changed to:', variantId);
}
```

**Use Cases:**

* Update URL query parameters
* Trigger custom analytics events
* Update external UI elements
* Sync variant selection with other page components

***

### 4. OnAddToCart

**Purpose:** Called immediately when the add-to-cart button is clicked, before the cart API request is made.

**Parameters:**

| Parameter   | Type   | Description                                                         |
| ----------- | ------ | ------------------------------------------------------------------- |
| `variantId` | Number | The variant ID being added to cart                                  |
| `utils`     | Object | Utility functions (see [Available Utilities](#available-utilities)) |

**Returns:** void

**Example:**

```javascript theme={null}
OnAddToCart: function OnAddToCart(variantId, utils) {
    // Show loading state
    document.querySelector('.custom-loader').classList.add('active');

    // Fire analytics event
    window.dataLayer?.push({
        event: 'bundle_add_to_cart',
        variantId: variantId
    });
}
```

**Use Cases:**

* Pre-cart validation
* Loading state UI updates
* Analytics event firing
* Custom cart payload modifications

***

### 5. OnAddedToCart

**Purpose:** Called after a successful add-to-cart API response.

**Parameters:**

| Parameter   | Type   | Description                                                         |
| ----------- | ------ | ------------------------------------------------------------------- |
| `variantId` | Number | The variant ID that was added to cart                               |
| `utils`     | Object | Utility functions (see [Available Utilities](#available-utilities)) |

**Returns:** void

**Example:**

```javascript theme={null}
OnAddedToCart: function OnAddedToCart(variantId, utils) {
    // Show success notification
    alert('Bundle added to cart!');

    // Open mini-cart
    document.querySelector('cart-drawer')?.classList.add('active');
}
```

**Use Cases:**

* Show success notifications
* Open mini-cart or cart drawer
* Redirect to cart page
* Fire conversion tracking events
* Update cart count in header

***

## Available Utilities

The `utils` object passed to each hook provides these functions:

| Function                                                   | Description                                                                       |
| ---------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `currencyFormatter(amount)`                                | Formats a numeric amount using the store's currency settings                      |
| `getComponentPrice(productId, selectedOptions, bundle)`    | Returns the price of a specific component based on the currently selected options |
| `getProductOptions(productId, bundle)`                     | Returns available options/variants for a product within the bundle                |
| `getVariantIdFromComponents(variants, selectedComponents)` | Resolves the variant ID from the current component selections                     |
| `getTranslations(options)`                                 | Returns resolved translation strings with interpolated values                     |
| `getTotalProductsInbundles(bundle)`                        | Returns the total number of products in the bundle                                |

## Support

If you need help with creating or customizing bundle hooks, contact our support team at [support@glood.ai](mailto:support@glood.ai)
