> For the complete documentation index, see [llms.txt](https://docs.iadvize.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.iadvize.dev/use-cases/data-and-analytics/track-iadvize-events-in-your-analytics-tool.md).

# Track iAdvize events in your Analytics tool

### Overview

When integrating iAdvize on your website, you may want to measure and analyse visitor engagement, conversation activity, and AI Shopping Assistant interactions within your existing analytics stack. Whether you use **Google Analytics 4**, **Adobe Analytics**, or **Piano Analytics**, the recommended approach is to push iAdvize events into the **dataLayer** and route them through your tag management system (e.g. Google Tag Manager).The iAdvize Web SDK exposes a set of lifecycle events covering the full visitor journey:

* iAdvize tag initialization
* Cookie and GDPR consent status
* Engagement rule triggers
* Widget impressions and clicks
* Shopping Panel state changes
* Conversation start and end
* Add-to-Cart actions from the AI Shopping Assistant

By listening to these events and forwarding them to the `window.dataLayer`, you gain full visibility into iAdvize engagement metrics alongside your existing analytics data, without requiring any direct integration with individual analytics platforms.

### Prerequisites

* The iAdvize main tag must be deployed on your website.
* `window.dataLayer` must be initialized (this happens automatically if Google Tag Manager is already in place).

> **Note:** Event names and property keys used in this guide are suggestions. Feel free to adapt them to your internal naming conventions.

### General Structure

All iAdvize event listeners must be registered inside the callback passed to `window.iAdvizeInterface.push`. This callback executes as soon as the iAdvize main tag is fully loaded and ready.

```javascript
window.dataLayer = window.dataLayer || [];
window.iAdvizeInterface = window.iAdvizeInterface || [];

window.iAdvizeInterface.push(function (iAdvize) {
  // Register all your iAdvize.on(...) listeners here
});
```

#### dataLayer Object Convention

All iAdvize-specific properties are grouped under an `iAdvize` key in each pushed object. This prevents naming collisions with other properties already present on your site.

```javascript
window.dataLayer.push({
  event: "iAdvize...",
  iAdvize: {
    property: "value"
  }
});
```

In Google Tag Manager, Data Layer Variables are accessible using dot notation: `iAdvize.widgetType`, `iAdvize.conversationId`, etc.

### Available Events

#### 1. iAdvize Main Tag Loaded

**When it fires:** As soon as the iAdvize main tag has finished loading and initializing on the page.

```javascript
window.iAdvizeInterface.push(function (iAdvize) {
  window.dataLayer.push({
    event: "iAdvizeMainTagLoaded"
  });
});
```

No additional properties. This event signals that the SDK is ready.

#### 2. Visitor Consent Status

**When it fires:**

* `get`: Returns the current consent value at the time of the call. Returns `null` if the visitor has not yet made a choice, `true` if accepted, `false` if refused.
* `on (change)`: Fires each time the cookie or GDPR consent value changes, typically when the visitor interacts with the consent banner, or implicitly when they start a conversation (both cookie and GDPR consents are automatically accepted upon conversation creation).

```javascript
// ── Cookie Consent ──
// Status on page load
window.dataLayer.push({
  event: "iAdvizeCookiesConsentStatus",
  iAdvize: {
    cookiesConsentValue: iAdvize.get("visitor:cookiesConsent") // true, false or null
  }
});

// Changes during the session
iAdvize.on("visitor:cookiesConsentChange", function (visitorCookiesConsent) {
  window.dataLayer.push({
    event: "iAdvizeCookiesConsentUpdated",
    iAdvize: {
      cookiesConsentValue: visitorCookiesConsent // true = accepted, false = refused
    }
  });
});

// ── GDPR Consent ──
// Status on page load
window.dataLayer.push({
  event: "iAdvizeGDPRConsentStatus",
  iAdvize: {
    gdprConsentValue: iAdvize.get("visitor:GDPRConsent") // true, false or null
  }
});

// Changes during the session
iAdvize.on("visitor:GDPRConsentChange", function (visitorGDPRConsent) {
  window.dataLayer.push({
    event: "iAdvizeGDPRConsentUpdated",
    iAdvize: {
      gdprConsentValue: visitorGDPRConsent // true = accepted, false = refused
    }
  });
});
```

| Event                          | GTM Key                       | Possible Values         |
| ------------------------------ | ----------------------------- | ----------------------- |
| `iAdvizeCookiesConsentStatus`  | `iAdvize.cookiesConsentValue` | `true`, `false`, `null` |
| `iAdvizeCookiesConsentUpdated` | `iAdvize.cookiesConsentValue` | `true`, `false`         |
| `iAdvizeGDPRConsentStatus`     | `iAdvize.gdprConsentValue`    | `true`, `false`, `null` |
| `iAdvizeGDPRConsentUpdated`    | `iAdvize.gdprConsentValue`    | `true`, `false`         |

#### 3. Engagement Rule Triggered

**When it fires:** When an engagement rule (also called a "targeting rule") is evaluated and executed on the visitor's side. This means:

1. The visitor meets the rule conditions (URL, time spent, pages viewed, etc.)
2. The rule is not capped (display limit not reached)
3. The `ruleId` is emitted only once per rule per page

> ⚠️ **Important distinction:** This event fires *before* the widget is displayed. A rule can be "triggered" but the widget may not appear (e.g. if the required CSS selector is not found on the page).

```javascript
iAdvize.on("engagementRule:triggered", function (ruleId) {
  window.dataLayer.push({
    event: "iAdvizeEngagementRuleTriggered",
    iAdvize: {
      engagementRuleId: ruleId
    }
  });
});
```

| GTM Key                    | Value              |
| -------------------------- | ------------------ |
| `iAdvize.engagementRuleId` | Engagement rule ID |

#### 4. Widget Displayed

**When it fires:** When a widget or notification is actually rendered on the page. This occurs *after*:

1. The engagement rule has been triggered (`engagementRule:triggered`)
2. Rendering prerequisites are met (CSS selector found for embedded buttons, viewport conditions, etc.)

```javascript
iAdvize.on("engagementNotification:displayed", function (notification) {
  window.dataLayer.push({
    event: "iAdvizeWidgetDisplayed",
    iAdvize: {
      widgetType: notification.type,
      widgetId: notification.id,
      engagementRuleId: notification.ruleId
    }
  });
});
```

| GTM Key                    | Value                                                                                                                                                 |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iAdvize.widgetType`       | `"BADGE"`, `"CLASSIC"`, `"MESSAGING"`, `"INVITATION"`, `"MINI_BADGE"`, `"CHATBOX"`, `"MESSAGE"`, `"CUSTOM_BUTTON"`, `"EMBEDDED_CONVERSATION_STARTER"` |
| `iAdvize.widgetId`         | Widget ID                                                                                                                                             |
| `iAdvize.engagementRuleId` | Associated engagement rule ID                                                                                                                         |

#### 5. Widget Clicked

**When it fires:** When the visitor clicks on a widget or notification and the engagement is accepted.

```javascript
iAdvize.on("engagementNotification:clicked", function (notification) {
  var properties = {
    widgetType: notification.type,
    widgetId: notification.id,
    engagementRuleId: notification.ruleId
  };

  // Only populated for Conversation Starters:
  // contains the text of the question the visitor clicked on
  if (notification.text) {
    properties.conversationStarterText = notification.text;
  }

  window.dataLayer.push({
    event: "iAdvizeWidgetClicked",
    iAdvize: properties
  });
});
```

| GTM Key                           | Value                                                                   |
| --------------------------------- | ----------------------------------------------------------------------- |
| `iAdvize.widgetType`              | Widget type                                                             |
| `iAdvize.widgetId`                | Widget ID                                                               |
| `iAdvize.engagementRuleId`        | Engagement rule ID                                                      |
| `iAdvize.conversationStarterText` | (Only for `EMBEDDED_CONVERSATION_STARTER`) Text of the clicked question |

#### 6. Shopping Panel State Change

**When it fires:**

* `OPENED`: When the Shopping Panel opens (click on notification, programmatic opening, conversation resumption)
* `REDUCED`: When the visitor minimizes the panel
* `CLOSED`: When the visitor fully closes the panel

```javascript
iAdvize.on("chatbox:statusChange", function (status) {
  window.dataLayer.push({
    event: "iAdvizeShoppingPanelStatusChanged",
    iAdvize: {
      shoppingPanelStatus: status // "OPENED", "REDUCED" or "CLOSED"
    }
  });
});
```

| GTM Key                       | Value                                 |
| ----------------------------- | ------------------------------------- |
| `iAdvize.shoppingPanelStatus` | `"OPENED"`, `"REDUCED"` or `"CLOSED"` |

#### 7. Conversation Started / Ended

**When it fires:**

* **Start** (`conversationId` changes from `null` to non-null): When a chat conversation is effectively created server-side. This occurs after the visitor clicks the widget and sends the initial message.
* **End** (`conversationId` changes from non-null to `null`): When the conversation is closed by the agent or the AI Shopping Assistant.

```javascript
iAdvize.on("conversation:idChange", function (conversationId, previousConversationId) {
  window.dataLayer.push({
    event: conversationId ? "iAdvizeConversationStarted" : "iAdvizeConversationEnded",
    iAdvize: {
      conversationId: conversationId || previousConversationId
    }
  });
});
```

| Case  | `event`                        | `iAdvize.conversationId` |
| ----- | ------------------------------ | ------------------------ |
| Start | `"iAdvizeConversationStarted"` | New conversation ID      |
| End   | `"iAdvizeConversationEnded"`   | Ended conversation ID    |

#### 8. Add to Cart Click (AI Shopping Assistant)

**When it fires:** When the visitor clicks [the "Add to Cart" button](https://help.iadvize.com/hc/en-gb/articles/25165287553298) on a product card recommended by the AI Shopping Assistant within the conversation.

> ⚠️ **Prerequisite:** The functional `addToCart:clicked` callback (with `resolve`/`reject`) must already be implemented in your site's native code for the Add to Cart button to appear in the conversation. Do not implement this analytics listener independently without the functional callback already in place, as it could activate the Add to Cart feature in iAdvize conversations before your site's cart logic is ready.

```javascript
// Analytics-only listener (does not interfere with the functional callback)
iAdvize.on("addToCart:clicked", function ({ productId }) {
  window.dataLayer.push({
    event: "iAdvizeAddToCartClicked",
    iAdvize: {
      productId: productId
    }
  });
});
```

To also track the outcome (success or failure), add the dataLayer pushes inside the existing functional callback:

```javascript
iAdvize.on("addToCart:clicked", function ({ productId, resolve, reject }) {
  addToCart(productId)
    .then(function (response) {
      if (response.success) {
        resolve(true);
        window.dataLayer.push({ event: "iAdvizeAddToCartSucceeded", iAdvize: { productId: productId } }); // ← add
      } else {
        resolve(false);
        window.dataLayer.push({ event: "iAdvizeAddToCartFailed", iAdvize: { productId: productId } }); // ← add
      }
    })
    .catch(function (error) {
      reject(error);
      window.dataLayer.push({ event: "iAdvizeAddToCartFailed", iAdvize: { productId: productId } }); // ← add
    });
});
```

| Event                         | Triggered when                | `iAdvize.productId` |
| ----------------------------- | ----------------------------- | ------------------- |
| `"iAdvizeAddToCartClicked"`   | Button clicked                | Product ID          |
| `"iAdvizeAddToCartSucceeded"` | Cart addition succeeded       | Product ID          |
| `"iAdvizeAddToCartFailed"`    | Cart addition failed or error | Product ID          |

### Full Consolidated Script

Here is a complete script combining all events described in this guide. You can implement it as-is or select only the events relevant to your use case. Event names can also be renamed to match your analytics taxonomy.

```javascript
window.dataLayer = window.dataLayer || [];
window.iAdvizeInterface = window.iAdvizeInterface || [];

window.iAdvizeInterface.push(function (iAdvize) {

  // ── 1. iAdvize main tag loaded ──
  window.dataLayer.push({
    event: "iAdvizeMainTagLoaded"
  });

  // ── 2a. Cookie consent - status on load ──
  window.dataLayer.push({
    event: "iAdvizeCookiesConsentStatus",
    iAdvize: {
      cookiesConsentValue: iAdvize.get("visitor:cookiesConsent")
    }
  });

  // ── 2b. Cookie consent - changes ──
  iAdvize.on("visitor:cookiesConsentChange", function (visitorCookiesConsent) {
    window.dataLayer.push({
      event: "iAdvizeCookiesConsentUpdated",
      iAdvize: {
        cookiesConsentValue: visitorCookiesConsent
      }
    });
  });

  // ── 2c. GDPR consent - status on load ──
  window.dataLayer.push({
    event: "iAdvizeGDPRConsentStatus",
    iAdvize: {
      gdprConsentValue: iAdvize.get("visitor:GDPRConsent")
    }
  });

  // ── 2d. GDPR consent - changes ──
  iAdvize.on("visitor:GDPRConsentChange", function (visitorGDPRConsent) {
    window.dataLayer.push({
      event: "iAdvizeGDPRConsentUpdated",
      iAdvize: {
        gdprConsentValue: visitorGDPRConsent
      }
    });
  });

  // ── 3. Engagement rule triggered ──
  iAdvize.on("engagementRule:triggered", function (ruleId) {
    window.dataLayer.push({
      event: "iAdvizeEngagementRuleTriggered",
      iAdvize: {
        engagementRuleId: ruleId
      }
    });
  });

  // ── 4. Widget displayed ──
  iAdvize.on("engagementNotification:displayed", function (notification) {
    window.dataLayer.push({
      event: "iAdvizeWidgetDisplayed",
      iAdvize: {
        widgetType: notification.type,
        widgetId: notification.id,
        engagementRuleId: notification.ruleId
      }
    });
  });

  // ── 5. Widget clicked ──
  iAdvize.on("engagementNotification:clicked", function (notification) {
    var properties = {
      widgetType: notification.type,
      widgetId: notification.id,
      engagementRuleId: notification.ruleId
    };
    if (notification.text) {
      properties.conversationStarterText = notification.text;
    }
    window.dataLayer.push({
      event: "iAdvizeWidgetClicked",
      iAdvize: properties
    });
  });

  // ── 6. Shopping Panel state change ──
  iAdvize.on("chatbox:statusChange", function (status) {
    window.dataLayer.push({
      event: "iAdvizeShoppingPanelStatusChanged",
      iAdvize: {
        shoppingPanelStatus: status
      }
    });
  });

  // ── 7. Conversation started / ended ──
  iAdvize.on("conversation:idChange", function (conversationId, previousConversationId) {
    window.dataLayer.push({
      event: conversationId ? "iAdvizeConversationStarted" : "iAdvizeConversationEnded",
      iAdvize: {
        conversationId: conversationId || previousConversationId
      }
    });
  });

  // ── 8. Add to Cart - click tracking ──
  // The SDK supports multiple listeners on addToCart:clicked.
  // This listener runs without interfering with the site's functional callback.
  iAdvize.on("addToCart:clicked", function ({ productId }) {
    window.dataLayer.push({
      event: "iAdvizeAddToCartClicked",
      iAdvize: {
        productId: productId
      }
    });
  });

});
```

### Connecting to Your Analytics Tool via GTM

#### Step 1 - Deploy the Tracking Script

Create a **Custom HTML tag** in GTM with the full script above. Use an **Initialization** trigger to fire it as early as possible in the page lifecycle.

> ⚠️ The `iAdvizeAddToCartSucceeded` and `iAdvizeAddToCartFailed` events require integration within the site's native source code, inside the existing functional `addToCart:clicked` callback.

#### Step 2 - Create GTM Data Layer Variables

In GTM, create **Data Layer Variable** variables using dot notation to access iAdvize properties:

| GTM Variable Name                   | dataLayer Path                    |
| ----------------------------------- | --------------------------------- |
| iAdvize - Cookies Consent Value     | `iAdvize.cookiesConsentValue`     |
| iAdvize - GDPR Consent Value        | `iAdvize.gdprConsentValue`        |
| iAdvize - Engagement Rule ID        | `iAdvize.engagementRuleId`        |
| iAdvize - Widget Type               | `iAdvize.widgetType`              |
| iAdvize - Widget ID                 | `iAdvize.widgetId`                |
| iAdvize - Conversation Starter Text | `iAdvize.conversationStarterText` |
| iAdvize - Shopping Panel Status     | `iAdvize.shoppingPanelStatus`     |
| iAdvize - Conversation ID           | `iAdvize.conversationId`          |
| iAdvize - Product ID                | `iAdvize.productId`               |

#### Step 3 - Create GTM Triggers

Create one **Custom Event** trigger per event you want to forward to your analytics tool. Then configure your analytics tags (GA4, Piano Analytics, Adobe Analytics, etc.) to fire on these triggers, using the Data Layer Variables defined above as event parameters.

| dataLayer Event                     | Suggested Analytics Use Case                    |
| ----------------------------------- | ----------------------------------------------- |
| `iAdvizeMainTagLoaded`              | Initialization / debug                          |
| `iAdvizeCookiesConsentStatus`       | Cookie consent audit on load                    |
| `iAdvizeCookiesConsentUpdated`      | Cookie consent change tracking                  |
| `iAdvizeGDPRConsentStatus`          | GDPR consent audit on load                      |
| `iAdvizeGDPRConsentUpdated`         | GDPR consent change tracking                    |
| `iAdvizeEngagementRuleTriggered`    | Active engagement rule measurement              |
| `iAdvizeWidgetDisplayed`            | Widget impression                               |
| `iAdvizeWidgetClicked`              | Widget click / Conversation Starter interaction |
| `iAdvizeShoppingPanelStatusChanged` | Panel open / minimize / close                   |
| `iAdvizeConversationStarted`        | Conversation start                              |
| `iAdvizeConversationEnded`          | Conversation end                                |
| `iAdvizeAddToCartClicked`           | Add to Cart click                               |
| `iAdvizeAddToCartSucceeded`         | Successful cart addition                        |
| `iAdvizeAddToCartFailed`            | Failed cart addition                            |

### End-to-End Example

This section walks through a complete, concrete example of sending the `iAdvizeConversationStarted` event to **Google Analytics 4** via Google Tag Manager. The same logic applies to any other event in this guide.

#### What we want to achieve

When a visitor starts a conversation with iAdvize, send a GA4 event named `iadvize_conversation_started` with the conversation ID as a custom parameter.

#### Step 1 - Push the event to the dataLayer

The following listener (already part of the consolidated script above) pushes the event when a conversation begins:

```javascript
iAdvize.on("conversation:idChange", function (conversationId, previousConversationId) {
  if (conversationId) {
    window.dataLayer.push({
      event: "iAdvizeConversationStarted",
      iAdvize: {
        conversationId: conversationId
      }
    });
  }
});
```

#### Step 2 - Create a Data Layer Variable in GTM

In GTM, go to **Variables > User-Defined Variables > New** and create a **Data Layer Variable**:

| Field                    | Value                       |
| ------------------------ | --------------------------- |
| Variable Name            | `iAdvize - Conversation ID` |
| Data Layer Variable Name | `iAdvize.conversationId`    |
| Data Layer Version       | Version 2                   |

#### Step 3 - Create a Custom Event Trigger in GTM

Go to **Triggers > New** and create a **Custom Event** trigger:

| Field        | Value                            |
| ------------ | -------------------------------- |
| Trigger Name | `iAdvize - Conversation Started` |
| Event Name   | `iAdvizeConversationStarted`     |
| Fire on      | All Custom Events                |

#### Step 4 - Create a GA4 Event Tag in GTM

Go to **Tags > New** and create a **Google Analytics: GA4 Event** tag:

| Field                | Value                                                            |
| -------------------- | ---------------------------------------------------------------- |
| Tag Name             | `GA4 - iAdvize Conversation Started`                             |
| Measurement ID       | Your GA4 Measurement ID (e.g. `G-XXXXXXXXXX`)                    |
| Event Name           | `iadvize_conversation_started`                                   |
| **Event Parameters** |                                                                  |
| Parameter Name       | `conversation_id`                                                |
| Parameter Value      | `{{iAdvize - Conversation ID}}` (the variable created in Step 2) |
| **Triggering**       | `iAdvize - Conversation Started` (the trigger created in Step 3) |

#### Step 5 - Verify in GA4 DebugView

1. Enable **Preview mode** in GTM and open your website.
2. Trigger a conversation with iAdvize.
3. In GTM Preview, confirm the tag `GA4 - iAdvize Conversation Started` fired on the `iAdvizeConversationStarted` event.
4. In GA4, open **Admin > DebugView** and verify the `iadvize_conversation_started` event appears with the `conversation_id` parameter populated.

Once validated, **submit and publish** your GTM container.

> 💡 **Reusable pattern:** This exact same flow applies to any other iAdvize event. Simply swap the trigger (`iAdvizeWidgetDisplayed`, `iAdvizeWidgetClicked`, etc.) and define the relevant event parameters using the corresponding Data Layer Variables.
