> For the complete documentation index, see [llms.txt](https://docs.carpose.de/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.carpose.de/events/03_example-google-integration.md).

# Example: Google Integration

#### Google Analytics 4 <a href="#google-analytics-4" id="google-analytics-4"></a>

```javascript
// Offer events
document.body.addEventListener('carpose-offer-select', function(event) {
  const offerData = event.detail.data;

  gtag('event', 'offer_select', {
    offer_id: offerData.id,
    offer_headline: offerData.headline,
    event_category: 'offer_interaction',
    event_label: offerData.subHeadline
  });
});

document.body.addEventListener('carpose-offer-contact-form-success', function(event) {
  const offerData = event.detail.data;

  gtag('event', 'offer_contact', {
    offer_id: offerData.id,
    offer_headline: offerData.headline,
    event_category: 'lead_generation',
    event_label: 'contact_form'
  });
});

// Vehicle events
document.body.addEventListener('carpose-vehicle-select', function(event) {
  const vehicleData = event.detail.data;

  gtag('event', 'vehicle_selected', {
    vehicle_id: vehicleData.id,
    vehicle_name: vehicleData.name,
    manufacturer: vehicleData.manufacturer,
    model: vehicleData.model,
    offer_number: vehicleData.offerNumber,
    event_category: 'vehicle_interaction'
  });
});

document.body.addEventListener('carpose-vehicle-contact-form-open', function(event) {
  const vehicleData = event.detail.data;

  gtag('event', 'vehicle_contact_form_open', {
    vehicle_id: vehicleData.id,
    vehicle_name: vehicleData.name,
    manufacturer: vehicleData.manufacturer,
    event_category: 'lead_generation',
    event_label: 'form_open'
  });
});

document.body.addEventListener('carpose-vehicle-contact-form-success', function(event) {
  const vehicleData = event.detail.data;

  gtag('event', 'vehicle_contact_submitted', {
    vehicle_id: vehicleData.id,
    vehicle_name: vehicleData.name,
    manufacturer: vehicleData.manufacturer,
    offer_number: vehicleData.offerNumber,
    event_category: 'lead_generation',
    event_label: 'contact_form'
  });
});

// data.origin — not detail.channel — is what tells you a search came from the AI assistant.
document.body.addEventListener('carpose-vehicle-search-submit', function(event) {
  const { filters, resultCount, origin } = event.detail.data;

  gtag('event', 'vehicle_search', {
    result_count: resultCount,
    search_origin: origin,
    event_category: origin === 'ai' ? 'ai_search' : 'form_search'
  });
});
```

### Google Tag Manager (dataLayer) <a href="#google-tag-manager-datalayer" id="google-tag-manager-datalayer"></a>

```javascript
// Offer events
document.body.addEventListener('carpose-offer-select', function(event) {
  const offerData = event.detail.data;

  if (window.dataLayer) {
    window.dataLayer.push({
      event: 'offer_interaction',
      offer_id: offerData.id,
      offer_headline: offerData.headline,
      offer_subheadline: offerData.subHeadline,
      interaction_type: 'selection'
    });
  }
});

document.body.addEventListener('carpose-offer-contact-form-success', function(event) {
  const offerData = event.detail.data;

  if (window.dataLayer) {
    window.dataLayer.push({
      event: 'lead_generation',
      offer_id: offerData.id,
      offer_headline: offerData.headline,
      lead_type: 'contact_request'
    });
  }
});

// Vehicle events
document.body.addEventListener('carpose-vehicle-select', function(event) {
  const vehicleData = event.detail.data;

  if (window.dataLayer) {
    window.dataLayer.push({
      event: 'vehicle_interaction',
      vehicle_id: vehicleData.id,
      vehicle_name: vehicleData.name,
      manufacturer: vehicleData.manufacturer,
      model: vehicleData.model,
      offer_number: vehicleData.offerNumber,
      interaction_type: 'selection'
    });
  }
});

document.body.addEventListener('carpose-vehicle-contact-form-open', function(event) {
  const vehicleData = event.detail.data;

  if (window.dataLayer) {
    window.dataLayer.push({
      event: 'vehicle_contact_form',
      vehicle_id: vehicleData.id,
      vehicle_name: vehicleData.name,
      manufacturer: vehicleData.manufacturer,
      form_action: 'open'
    });
  }
});

document.body.addEventListener('carpose-vehicle-contact-form-success', function(event) {
  const vehicleData = event.detail.data;

  if (window.dataLayer) {
    window.dataLayer.push({
      event: 'lead_generation',
      vehicle_id: vehicleData.id,
      vehicle_name: vehicleData.name,
      manufacturer: vehicleData.manufacturer,
      offer_number: vehicleData.offerNumber,
      lead_type: 'vehicle_contact_form'
    });
  }
});
```

#### One Trigger for the Whole Vehicle-Search Experience <a href="#one-trigger-for-the-whole-vehicle-search-experience" id="one-trigger-for-the-whole-vehicle-search-experience"></a>

Because every event that touches vehicle data — the search results, the wishlist, the comparison tray, the AI assistant, and so on — shares the `carpose-vehicle-` prefix and the same v2 envelope, you don't need a separate GTM trigger per event name. A single "Custom Event" trigger matching the prefix, paired with variables that read `feature`, `action`, `channel` and `data.origin` off the envelope, covers the whole surface:

```javascript
// One trigger for the whole vehicle-search experience; split by detail fields in GTM.
['select', 'contact-phone', 'contact-mail', 'contact-whatsapp', 'wishlist-add', 'comparison-add'].forEach(function (suffix) {
    document.body.addEventListener('carpose-vehicle-' + suffix, function (event) {
        var d = event.detail;
        window.dataLayer && window.dataLayer.push({
            event: 'carpose_' + d.type + '_' + d.action,
            carpose_entity: d.type,
            carpose_feature: d.feature || '',
            carpose_action: d.action,
            carpose_channel: d.channel || '',
            // origin only exists on carpose-vehicle-search-submit; it is what distinguishes
            // an AI-driven search from a form search, since channel is "form" for both.
            carpose_origin: (d.data && d.data.origin) || '',
            carpose_component: d.component,
            carpose_data: d.data,
        });
    });
});
```

In GTM itself, configure a Custom Event trigger with the event name set to match `carpose-vehicle-.*` (regex match), then define Data Layer Variables for `carpose_feature`, `carpose_action`, `carpose_channel`, `carpose_origin` and `carpose_component` to slice reporting without adding a new trigger every time a vehicle event is added to the catalogue.
