> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://docs.intractive.app/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Google Tag Manager (GTM)

### What is Google Tag Manager (GTM)?
Google Tag Manager is a free tool that lets you add and manage scripts ("tags") on your website through one dashboard — without editing the site's code every time. You install GTM once, and from then on you add, change, and remove tags from the GTM interface instead of asking a developer.
Three concepts do all the work:
* **Tags** — the snippet that actually runs (an analytics pixel, a tracking script, or an embed).
* **Triggers** — the *when*: the condition that fires the tag (e.g. on every page, or only on `/story/*`).
* **Variables** — the *values* a tag or trigger reads (page URL, a click, a `dataLayer` value).

### How to setup Google Tag Manager in Intractive
1. In [Google Tag Manager](https://tagmanager.google.com/), open the container for this Project.
2. Copy the container ID from the top of the workspace; it looks like `GTM-XXXXXXX`.
3. In Intractive, go to **Project settings → Tracking & scripts** and paste the ID into the **Google Tag Manager ID** field.
4. And hit save.

That’s the only Intractive-side step. Everything else (which tags fire, which triggers, consent rules) stays in GTM.


![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-1_13u83ep.png)

### Track Story events in GA4
Once GTM is loading on your Project, you can send Intractive's own Story events straight into GA4. While a Story plays, Intractive pushes a small set of events onto `window.dataLayer` — you pick them up in GTM as triggers, then forward them to GA4 as events. No developer needed.

Intractive fires three events:
* **`intractiveStoryProgress`** : fires as the player moves through the Story, typically each time they finish a content block. Carries `storyId`, `sessionId`, `progress`, `depth`, and `total`.
* **`intractiveVariablesUpdated`** : fires whenever a Story variable changes value. Carries a `variables` object with the full current map. Useful if you're tracking scoring or branching.
* **`intractiveOutboundLink`** : fires when a player follows a link out of the Story. Carries `storyId`, `sessionId`, and the destination `url` (with any UTM parameters already appended).

| 💡Note: for a "how far did they get" metric, use depth, not progress. Because a Story's total block count can grow mid-session when a player triggers a branch, progress (and anything you calculate from total) can move backwards between pushes which makes for confusing funnel and retention reports. depth only ever counts up, so it's the clean signal.

### **intractiveStoryProgress**
Fired when the player’s progress through the Story changes, typically every time they finish a content block.
| Field | Type | Description |
| ---- | ---- | ---- |
| `event` | `string` | Always `"intractiveStoryProgress"`. |
| `storyId` | `string` | Internal ID of the Story. |
| `sessionId` | `string` | ID of this play through, unique per player visit. |
| `progress` | `number` | Percent complete, **rounded to a whole number** (0–100). |
| `depth` | `number` | 1-based index of the content block the player is currently on. Always at least `1`. |
| `total` | `number` | Total number of content blocks currently in scope for this play through. 
**This value can grow during the session** if the player triggers a branch that activates additional blocks. |

### **intractiveVariablesUpdated**
Fired whenever any of the Story’s variables change value. Useful if you’ve set up scoring or branching variables and want to surface them in your analytics.
| Field | Type | Description |
| ---- | ---- | ---- |
| `event` | `string` | Always `"intractiveVariablesUpdated"`. |
| `variables` | `object` | A `{ [variableId: string]: string }` map of every variable currently in scope and its current value. 
The event re-pushes the **full** map on each change. |

### **intractiveOutboundLink**
Fired when the player follows a link out of the Story. Redirect blocks, inline links in text, and button URLs all count.
| Field | Type | Description |
| ---- | ---- | ---- |
| `event` | `string` | Always `"intractiveOutboundLink"`. |
| `storyId` | `string` | Internal ID of the Story. |
| `sessionId` | `string` | Session ID. |
| `url` | `string` | The destination URL the player is being sent to. 
UTM parameters that Intractive appends are already included here. |

## Google Tag Manager setup - intractiveStoryProgress
This walkthrough sends the **`intractiveStoryProgress`** event to GA4 as an event called `story_progress`, carrying how far the player got (`depth`) and which Story it was (`storyId`). Once you've done one, the other two events follow the same pattern.
You'll build three things in GTM: a **trigger** (when to fire), two **variables** (which values to grab), and a **tag** (what to send to GA4).

**Step 1: Create the trigger.** In your GTM container, go to **Triggers → New → Trigger Configuration** and choose **Custom Event**.


![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-2_1aqtalo.png)
![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-3_zqar33.png)

In the **Event name** field, type `intractiveStoryProgress` exactly (it's case-sensitive). Select when the trigger needs to be activated.
In this case we would like to know how many viewer have seen 3 or more story content blocks.

Select some customized events and select `{{Story Depth}}` and match the conditions.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-4_lbp2s0.png)


**Step 2: Create a Data Layer Variable for each field you want.** GTM can't send a field to GA4 until you've "captured" it as a variable.
Go to **Variables → User-Defined Variables → New → Variable Configuration → Data Layer Variable**.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-5_3fcp6i.png)
In the **Data Layer Variable Name** field, type the field name exactly as Intractive pushes it, start with `depth`. You can also add the variables you have created in the stories.

| 💡Note: the Data Layer Variable Name must match the field name from the table above character-for-character — depth, storyId, sessionId, url. A typo here doesn't error; the value just comes through empty, which is the usual reason a parameter shows up blank in GA4.


**Step 3: Create the GA4 Event tag.** Go to **Tags → New → Tag Configuration → Google Analytics: GA4 Event**.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-6_lu8m50.png)


* Set **Measurement ID** to your GA4 property (or select your existing GA4 Configuration tag if you have one).
## Find your measurement ID
To find the measurement ID, follow these steps:
1. In [**Admin**](https://analytics.google.com/analytics/web/provision/#/provision), under *Data collection and modification*, click **Data streams**.
2. Select the **Web** tab.
3. Click the web data stream.
4. Find the measurement ID in the first row of the stream details.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-7_10rjjhz.png)


* In **Event Name**, this is the name you'll see in GA4. We used `engaged_visitors` because we would like to see how many of the visitors have visit 3 or more content blocks.
* Under **Triggering**, choose the trigger from Step 1.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-8_18bxchb.png)

* **Hit Save.**


**Step 4: Preview before you publish.** Click **Preview** (top right), enter the URL of a *published* Story, and play through it. You can find the URL story in our platform via the share button top right corner.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-9_10orq52.png)
![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-10_13ei123.png)

In the **Tag Assistant** debug panel you should see `intractiveStoryProgress` fire each time you finish a content block, your `story_progress` tag fire alongside it, and `depth` climbing 1, 2, 3… If a parameter is empty, recheck the variable name in Step 2.

**Step 5: Publish.** Back in the container, click **Submit**, name the version (e.g. "Add Intractive story\_progress tracking"), and **Publish**.

Events now flow to GA4, they'll appear in realtime within a minute or two.

## **Google Tag Manager setup - intractiveOutboundLink**

**Would you like to measure an outbound link?**
Setup the Trigger with the exact name `intractiveOutboundLink`. Then you search for your trigger `{{Page url outbound link}}`. When you don’t see these events in this dropdown menu, please go to Intractive and refresh your story. Double check if your story is published.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-11_x81e3i.png)
![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-12_1f0afnp.png)

Setup the variables
Go to **Variables → User-Defined Variables → New → Variable Configuration → Data Layer Variable**.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-13_1rv5y2f.png)


In the **Data Layer Variable Name** field, type the field name exactly as Intractive pushes it, start with `depth`. You can also add the variables you have created in the stories.

| 💡 Note: the Data Layer Variable Name must match the field name from the table above character-for-character — depth, storyId, sessionId, url. A typo here doesn't error; the value just comes through empty, which is the usual reason a parameter shows up blank in GA4.

**Create the GA4 Event tag.** Go to **Tags → New → Tag Configuration → Google Analytics: GA4 Event**.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-14_zxe2k3.png)


* Set **Measurement ID** to your GA4 property (or select your existing GA4 Configuration tag if you have one).

## Find your measurement ID
To find the measurement ID, follow these steps:
1. In [**Admin**](https://analytics.google.com/analytics/web/provision/#/provision), under *Data collection and modification*, click **Data streams**.
2. Select the **Web** tab.
3. Click the web data stream.
4. Find the measurement ID in the first row of the stream details.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-7_byvxk9.png)

* In **Event Name**, this is the name you'll see in GA4.
* Under **Triggering**, choose the trigger from Step 1.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-15_l8mygu.png)


**Step 4: Preview before you publish.** Click **Preview** (top right), enter the URL of a *published* Story, and play through it. You can find the URL story in our platform via the share button top right corner.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-9_bg10lv.png)
![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-10_13qt9bd.png)

In the **Tag Assistant** debug panel you should see `intractiveOutboundLink` .

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-16_1ynn6mn.png)
**Step 5: Publish.** Back in the container, click **Submit**, name the version (e.g. "Add Intractive story\_progress tracking"), and **Publish**.
Events now flow to GA4, they'll appear in realtime within a minute or two.

## Google Tag Manager setup - Variables
When you would like to measure variables in Google Analytics you can use this setup.

### **intractiveVariablesUpdated**
Fired whenever any of the Story’s variables change value. Useful if you’ve set up scoring or branching variables and want to surface them in your analytics.

| Field | Type | Description |
| ---- | ---- | ---- |
| `event` | `string` | Always `"intractiveVariablesUpdated"`. |
| `variables` | `object` | A `{ [variableId: string]: string }` map of every variable currently in scope and its current value. 
The event re-pushes the **full** map on each change. |

Setup the Trigger with the exact name `intractiveOutboundLink`. Then you search for your trigger Variable. When you don’t see these events in this dropdown menu, please go to Intractive and refresh your story. Double check if your story is published.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-17_19aqy6n.png)
Setup the variables
Go to **Variables → User-Defined Variables → New → Variable Configuration → Data Layer Variable**.
![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-18_1wk8cmv.png)

**Create the GA4 Event tag.** Go to **Tags → New → Tag Configuration → Google Analytics: GA4 Event**.

![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-19_1evxe1s.png)
![](https://storage.crisp.chat/users/helpdesk/website/-/a/f/c/4/afc4fa0dc4a39800/gtm-20_ro8p5y.png)