---
title: Google Tag Manager
slug: google-tag-manager
createdAt: 2025-05-29T21:58:55.644Z
---

# Introduction

**Google Tag Manager (GTM)&#x20;**&#x69;s a tag management system that lets you add and update website tags—like tracking pixels and analytics scripts—without changing the site’s code. It simplifies tracking setup and improves marketing agility.

# Getting started

This is a **device-mode** destination. You will need the relevant **Container ID** of your Google Tag Manager Workspace to connect this destination. You can find this information by following the steps below:&#x20;

- Log into your Google Tag Manager Workspace homepage.
- Navigate to the upper right-hand corner of the page and locate the Container ID.

# Connecting to the Google Tag Manager CDP destination

:::hint{type="danger"}
Before connecting destinations in the Chord CDP, please verify with all Destination owners that all **non-Chord CDP** configured destinations are *disabled.*
**
Running external destinations alongside configured Chord CDP destinations ***can result in duplicate events downstream.&#x20;***
:::

1. Log into the Chord data platform.
2. Navigate to the CDP.
3. Click the **"Add"&#x20;**&#x62;utton next to Destinations.
4. Select **Google Tag Manager&#x20;**&#x66;rom the destination catalog.
5. Enter in the **Destination Name, the Container ID, and Data Layer Name**&#x20;

   - `Destination Name`- The arbitrary name you give to the destination
   - `Container ID`- The GTM Container ID is found in your ***Google Tag Manager*** account.
     - **How to Find It**
       1. Go to [https://tagmanager.google.com](https://tagmanager.google.com)
       2. Select your account and container
       3. The Container ID is displayed at the top of the workspace - it looks like **GTM-XXXXXXX**
   - `Data Layer Name`- The *dataLayerName* field specifies the name of the JavaScript array that GTM uses to receive data on the page.

     - **How to Find It**
       1. Go to [https://tagmanager.google.com](https://tagmanager.google.com)
       2. Navigate to the *Variables&#x20;*&#x73;ettings in the left-hand pane
       3. Look for any configured `Data Layer Variables`&#x20;
       4. If there isn't an explicit variable configured, this value will **default to `dataLayer`**

     ::Image[]{src="https://api.archbee.com/api/optimize/TmutqdeXiIw-V3gBZXVjd/wHPDEFXafVQ1aEqYjSJj-_image-5.png" size="80" width="1922" height="1110" position="center" darkWidth="1922" darkHeight="1110" showCaption="false"}

   ::Image[]{src="https://api.archbee.com/api/optimize/TmutqdeXiIw-V3gBZXVjd/QvlFXMXOESTSbgTETGzpd_image-6.png" size="80" width="615" height="533" position="center" darkWidth="615" darkHeight="533" showCaption="false"}
6. Click **"Create"&#x20;**&#x74;o connect.

# Events

All events push data to the Data Layer via `dataLayer.push(eventData)`, followed by a `dataLayer.push(function() { this.reset() })` call to clear the Data Layer state for the next event.

## Page

Pushes a page event to the Data Layer.

**Data Layer push:**

| Data Layer Key | Chord Source                          | Notes                  |
| -------------- | ------------------------------------- | ---------------------- |
| `event`        | *(hardcoded)* `"page"`                |                        |
| `userId`       | `userId` > `""`                       |                        |
| `anonymousId`  | `anonymousId` > `""`                  |                        |
| `name`         | `properties.title` > `""`             |                        |
| `url`          | `properties.url` > `""`               |                        |
| `title`        | `properties.title` > `""`             |                        |
| `properties`   | `properties`                          | Full properties object |
| `traits`       | `traits` merged with `context.traits` |                        |

***

## Identify

Pushes an identify event to the Data Layer.

**Data Layer push:**

| Data Layer Key | Chord Source                          | Notes |
| -------------- | ------------------------------------- | ----- |
| `event`        | *(hardcoded)* `"identify"`            |       |
| `userId`       | `userId` > `""`                       |       |
| `anonymousId`  | `anonymousId` > `""`                  |       |
| `email`        | `properties.email` > `""`             |       |
| `name`         | `properties.name` > `""`              |       |
| `traits`       | `traits` merged with `context.traits` |       |

***

## Track

Pushes the track event to the Data Layer using the Chord event name directly.

**Data Layer push:**

| Data Layer Key | Chord Source                               | Notes                                                                                                      |
| -------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `event`        | `event` (the Chord event name) > `"track"` |                                                                                                            |
| `userId`       | `userId` > `""`                            |                                                                                                            |
| `anonymousId`  | `anonymousId` > `""`                       |                                                                                                            |
| `currency`     | `properties.currency` > `""`               |                                                                                                            |
| `properties`   | `properties`                               | Full properties object, including `properties.products[]`, `properties.total`, `properties.order_id`, etc. |
| `traits`       | `traits` merged with `context.traits`      |                                                                                                            |

All track events are forwarded with no event-name-specific mapping. GTM tags and triggers handle the routing. All tracking plan fields are available under the `properties` key in the Data Layer (e.g., `properties.products[0].name`, `properties.products[0].price`, `properties.total`).

## Initialization

The plugin initializes the Data Layer array with the `user_id` from the first event, pushes a `gtm.start` timestamp event, then loads the GTM container script from `googletagmanager.com/gtm.js?id={containerId}`. If a custom `dataLayerName` is configured, it is passed as the `&l=` parameter.

The plugin manages SDK loading state (`fresh` → `loading` → `loaded`/`failed`) to prevent duplicate script loads. If the script fails to load, subsequent events are silently dropped.

## CSP Requirements

If your site uses a Content Security Policy, allow the following domains:

| Directive     | Domain                             |
| ------------- | ---------------------------------- |
| `script-src`  | `https://www.googletagmanager.com` |
| `connect-src` | `https://www.googletagmanager.com` |

