> ## 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).

# Meta - Sending story events to Google Analytics 4

# Sending story events to Google Analytics 4
This article walks through connecting a story to Google Analytics 4, so you can see how many people started a story, where they dropped off, what they answered and how many clicked through.

Read Story events with Google Tag Manager first if you haven't — it explains the data layer events this article builds on.

| 💡 In one sentence: you create a handful of variables and triggers in Tag Manager, point them at your Analytics measurement ID, and then register the extra details in Analytics so they show up in reports.

# Before you start
| What you need | Looks like | Where to find it |
| ---- | ---- | ---- |
| Tag Manager container ID | `GTM-XXXXXXX` | Tag Manager, top right of the workspace. Already pasted into Project settings. |
| Analytics measurement ID | `G-XXXXXXXXXX` | Analytics → **Admin** → **Data streams** → your web stream |

On the data stream screen you'll also see a **Google tag ID** starting with `GT-`. Both work, but take the one starting with **`G-`** — that's what the steps below expect.

If no Analytics property exists yet, create one first: Analytics → **Admin** → **Create property**, then add a **Web** data stream for `web.intractive.app`. Set the time zone and currency to the client's, not the default.
# Step 1 — Add the Google tag
This is the tag that loads Analytics on the page. Everything else depends on it.
1. In Tag Manager, go to **Tags** → **New**
2. Tag type: **Google tag**
3. Tag ID: your `G-XXXXXXXXXX`
4. Trigger: **Initialization - All Pages**
5. Name it `GA4 - Config` and save

| 💡 The Tag ID field is the single point where Tag Manager and Analytics meet. Everything else in the container decides when to send something; this decides where it goes.

# Step 2 — Create the variables
Variables pull the details out of each story event so you can use them. Create these under **Variables** → **New** → **Data Layer Variable**, leaving the version at its default.
| Name it | Data layer variable name | What it gives you |
| ---- | ---- | ---- |
| `DLV - storyId` | `storyId` | Which story |
| `DLV - sessionId` | `sessionId` | Ties one visitor's run together |
| `DLV - progress` | `progress` | Percentage complete |
| `DLV - depth` | `depth` | Which block they're on |
| `DLV - total` | `total` | How long the story is |
| `DLV - outboundUrl` | `url` | Which link was clicked |

The right-hand column must match the story's field names **exactly**, including capital letters. `storyid` will not work where `storyId` is expected. A variable that comes back empty in testing is almost always a capitalisation slip here.

To capture a specific answer, add one more Data Layer Variable per answer you care about, using the variable name from your story with `variables.` in front of it — for example `variables.timeline` for a story variable called `timeline`.
# Step 3 — Create the triggers
Triggers decide when a tag fires. All of these are **Custom Event** triggers, created under **Triggers** → **New**.
| Name it | Event name | Condition |
| ---- | ---- | ---- |
| `CE - Story Progress` | `intractiveStoryProgress` | All custom events |
| `CE - Story Start` | `intractiveStoryProgress` | `DLV - depth` equals `1` |
| `CE - Story Halfway` | `intractiveStoryProgress` | `DLV - progress` greater than or equal to `50` |
| `CE - Story Complete` | `intractiveStoryProgress` | `DLV - progress` equals `100` |
| `CE - Variables Updated` | `intractiveVariablesUpdated` | All custom events |
| `CE - Outbound Link` | `intractiveOutboundLink` | All custom events |

|| ⚠️ This one setting prevents inflated numbers. The halfway and complete triggers use conditions that keep matching on every later progress message. On any tag using them, open Advanced Settings → Tag firing options and choose Once per page. A story is one page load, so once per page means once per story. Without it you'll record a completion for every remaining block, and your conversion count will be several times too high.


# Step 4 — Create the event tags
One tag per event you want in Analytics. All are type **Google Analytics: GA4 Event**, with the measurement ID set to your `G-` ID.
| Event name to send | Details to include | Trigger | Once per page? |
| ---- | ---- | ---- | ---- |
| `intractive_story_start` | story_id, session_id, total_blocks | `CE - Story Start` | No |
| `intractive_block_view` | story_id, session_id, block_index, total_blocks, progress | `CE - Story Progress` | No |
| `intractive_progress_50` | story_id, session_id | `CE - Story Halfway` | **Yes** |
| `intractive_story_complete` | story_id, session_id, total_blocks | `CE - Story Complete` | **Yes** |
| `intractive_answer` | story_id, session_id, plus the answers you chose | `CE - Variables Updated` | No |
| `intractive_outbound_click` | story_id, session_id, link_url | `CE - Outbound Link` | No |
| Each detail is added under **Event Parameters** as a name and a value, where the value is the matching variable from step 2 — for example parameter `story_id` with value `{{DLV - storyId}}`. |  |  |  |


**`intractive_block_view`** **fires once per content block**, so roughly 12 to 20 events for a completed story. That volume is what makes drop-off analysis possible — "we lose 40% of viewers at block 4" — and it's well inside Analytics' free limits. If a client's reports feel noisy, this is the first tag to switch off.

# Step 5 — Register the details in Analytics
**This step is easy to skip and nothing works properly without it.** Analytics collects your extra details but will not report on them until you register each one by hand.

Go to Analytics → **Admin** → **Custom definitions** and add these, all event-scoped:
| Register as | Name | Event parameter |
| ---- | ---- | ---- |
| Custom dimension | Story ID | `story_id` |
| Custom dimension | Session ID | `session_id` |
| Custom dimension | Link URL | `link_url` |
| Custom metric (integer) | Block index | `block_index` |
| Custom metric (integer) | Total blocks | `total_blocks` |
| Custom metric (integer) | Progress | `progress` |

Then go to **Admin** → **Events** → **Key events** and mark `intractive_story_complete` as a key event, so it counts as a conversion and can be imported into Google Ads.

# Step 6 — Test, then publish
1. In Tag Manager click **Preview** and enter a published story link
2. Tap through the story. You should see `intractiveStoryProgress` once per block, then `intractiveVariablesUpdated` when you answer, then `intractiveOutboundLink` if you click out
3. Click an event and check the **Variables** tab: your `DLV -` variables should have values, not `undefined`
4. Finish the story and confirm the complete tag fired **once**, not once per remaining block
5. In Analytics, open **Admin** → **DebugView** to watch the same events arrive with their details
6. Back in Tag Manager, click **Submit** to publish. Nothing reaches real visitors until you do

|| ⚠️ After publishing, your own browser may keep serving the previous version of the container for up to 15 minutes. If your changes don't seem to be live, do a hard refresh before assuming something is broken. See Troubleshooting story tracking.

# Reading the results
With the events flowing, the two reports worth living in are:
* **Reports → Engagement → Events** for volumes per event
* **Explore** for a free-form drop-off view: put `block_index` against event count to see exactly which block loses people
That drop-off curve is the single most useful thing this setup gives you. The block where the curve flattens is the point where viewers commit — everyone past it tends to finish.

✅ **Quick checklist**
* Take the `G-` ID, not the `GT-` one.
* Data layer variable names are case-sensitive.
* Set **Once per page** on the halfway and complete tags.
* Register custom definitions in Analytics, or your details stay invisible.
* Mark the completion event as a key event.
* Test in Preview, then Submit. Allow 15 minutes for the cache.