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

# Custom Events

> Send custom analytics events from your Ollie Shop components to Google Tag Manager

While Ollie Shop automatically tracks standard e-commerce events, you may want to track additional user interactions specific to your business. Custom events allow you to measure engagement with promotional banners, loyalty programs, form interactions, and any other checkout elements you've built.

## Real-World Example: VIP Enrollment

Imagine you've added a VIP program enrollment option to your checkout. When customers opt-in, you want to track this decision in your analytics to measure program adoption and correlate it with purchase behavior.

Here's how a custom component can send a `vip_enrollment` event when a customer joins:

```typescript VipEnrollmentButton.tsx theme={"system"}
'use client'

import React from 'react';
import styles from './vipEnrollmentButton.module.css';

export default function VipEnrollmentButton() {
  const handleEnrollment = () => {
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
      event: 'vip_enrollment',
      enrollment_source: 'checkout'
    });
  };

  return (
    <button onClick={handleEnrollment} className={styles.button}>
      Join VIP Program
    </button>
  );
}
```

When a customer clicks the button, the `vip_enrollment` event is pushed to the `dataLayer`, where GTM captures it and forwards it to GA4 or any other analytics platform you've configured.

<Tip>
  You can [enrich this event with session data](/ollie-shop/analytics/gtm-enrichment) using GTM Custom HTML tags—for example, adding customer segment or cart value context.
</Tip>

## How It Works

Custom events are sent to Google Tag Manager via the `dataLayer` object—a JavaScript array that GTM uses as a communication layer between your website and tags.

```typescript theme={"system"}
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: 'your_event_name',
  // ... additional parameters
});
```

<Info>
  Learn more about the dataLayer in the [GTM dataLayer documentation](https://developers.google.com/tag-platform/tag-manager/datalayer).
</Info>

## Prerequisites

* Ollie Shop [SDK](/ollie-shop/api/index) installed
* [Google Tag Manager](/ollie-shop/configuration/integrations) configured in your store
* A [custom component](/ollie-shop/customization/custom-component) to add the event tracking

## Implementation Details

Add this type declaration at the top of your custom component to get type safety and IDE autocompletion for the `dataLayer`:

```typescript theme={"system"}
declare global {
  interface Window {
    dataLayer?: Record<string, unknown>[];
  }
}
```

<Accordion title="Full Component Example">
  ```typescript VipEnrollmentButton.tsx theme={"system"}
  'use client'

  import React from 'react';
  import styles from './styles.module.css';

  declare global {
    interface Window {
      dataLayer?: Record<string, unknown>[];
    }
  }

  export default function VipEnrollmentButton() {
    const handleEnrollment = () => {
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({
        event: 'vip_enrollment',
        enrollment_source: 'checkout'
      });
    };

    return (
      <button onClick={handleEnrollment} className={styles.button}>
        Join VIP Program
      </button>
    );
  }
  ```
</Accordion>

## Event Naming Best Practices

Follow these conventions to keep your analytics data clean and actionable:

| Convention          | Example                    | Description                         |
| ------------------- | -------------------------- | ----------------------------------- |
| Use snake\_case     | `vip_enrollment`           | Consistent with GA4 standard events |
| Be descriptive      | `shipping_method_selected` | Makes reports easier to understand  |
| Include context     | `checkout_promo_applied`   | Helps segment by checkout stage     |
| Avoid generic names | `button_click`             | Too vague for meaningful analysis   |

<Warning>
  Event names in GA4 are case-sensitive and limited to 40 characters. Avoid spaces and special characters. See [GA4 event naming rules](https://support.google.com/analytics/answer/13316687).
</Warning>

## Configuring GTM to Capture Custom Events

After pushing events to the `dataLayer`, configure GTM to capture and forward them:

1. Create a **Custom Event Trigger** in GTM matching your event name (e.g., `vip_enrollment`)
2. Create a **GA4 Event Tag** that fires on this trigger
3. Map any custom parameters to GA4 event parameters
4. Test using GTM's Preview mode before publishing

<Tip>
  Use [GTM's Preview mode](https://support.google.com/tagmanager/answer/6107056) to verify events are being captured correctly before publishing your container.
</Tip>

## Further Reading

* [GA4 Custom Events Guide](https://developers.google.com/analytics/devguides/collection/ga4/events)
* [GTM dataLayer Documentation](https://developers.google.com/tag-platform/tag-manager/datalayer)
* [GA4 Event Naming Rules](https://support.google.com/analytics/answer/13316687)
