# How to track YouTube videos in GA4 with GTM (and why enhanced measurement misses plays)

**Author:** Piotr Litwa - GTM & Analytics Specialist  
**Published:** 2026-09-25  
**URL:** https://piotrlitwa.com/articles/en/youtube-video-tracking-ga4.html  
**Language:** en  
**Keywords:** youtube video tracking ga4, gtm youtube video trigger, ga4 video_progress, track embedded youtube videos, youtube-nocookie gtm

---

YouTube video tracking in GA4 works two ways. Enhanced measurement sends `video_start`, `video_progress` (at 10%, 25%, 50% and 75%) and `video_complete` for embedded YouTube players that have the JavaScript API enabled. Google Tag Manager's **YouTube Video** trigger gives you the same signals with your own thresholds, your own event names and a fix for embeds that don't have the API switched on.

If your videos sit in a plain iframe that loads with the page, enhanced measurement might be all you need. If they load late, sit behind a cookie banner, or hide behind a click-to-play thumbnail, it will quietly report nothing. And "nothing" looks exactly like "nobody watched".

> **Key Takeaways**
> - Enhanced measurement only tracks YouTube embeds with JS API support, which means `enablejsapi=1` in the iframe URL. Page builders don't add it by default.
> - The GTM YouTube Video trigger can add the API parameter for you. It only works if a YouTube video or the IFrame API script is on the page when GTM loads.
> - Click-to-play facades and CMP placeholders create the iframe later. That's where both methods lose plays.
> - `video_start` and `video_progress` are reserved GA4 event names. Pick your own names in GTM, and switch off the enhanced measurement toggle so you don't count twice.
> - `youtube-nocookie.com` reduces cookies before playback. It doesn't make the embed consent-free.

## What GA4 tracks by itself

Enhanced measurement lives in Admin > Data streams > your web stream > Enhanced measurement. The **Video engagement** toggle sends three events:

- `video_start` when playback begins
- `video_progress` when the video passes 10%, 25%, 50% and 75% of its duration
- `video_complete` when it ends

Each one carries `video_current_time`, `video_duration`, `video_percent`, `video_provider`, `video_title`, `video_url` and `visible`. Video provider, Video title and Video URL show up as ready-made dimensions in GA4. The rest need custom definitions, more on that below.

The catch is one line in Google's documentation: these events fire "for YouTube embedded videos that have JS API support enabled". In plain terms, the iframe `src` needs `enablejsapi=1`.

A standard copy-paste embed from YouTube's Share > Embed menu doesn't include it. WordPress oEmbed doesn't add it. Most page builders don't either.

So the default case on a typical site is this: toggle on, tracking off.

## Enhanced measurement vs the GTM YouTube Video trigger

| | Enhanced measurement | GTM YouTube Video trigger |
|---|---|---|
| Setup | One toggle | Trigger + tag, 30-45 minutes |
| Needs `enablejsapi=1` | Yes, you add it yourself | Can add it for you (checkbox) |
| Progress points | Fixed: 10, 25, 50, 75% | Your choice: percentages or seconds |
| Pause, seek, buffering | No | Yes, optional |
| Event names | `video_start`, `video_progress`, `video_complete` | Your own, like `yt_start` |
| Videos added after page load | Unreliable | Works if a video or the IFrame API is present at GTM load |
| Filter which videos | No | Yes, Some Videos with conditions |
| Change history | None | Container versions |

My take: for a blog with two embedded talks, the toggle plus `enablejsapi=1` is fine. For a course platform, a product page with demo videos, or anything where a view counts as a lead signal, I build it in GTM.

## Why the numbers vanished: a story about a facade

Ola runs marketing for a language school in Gdańsk. Her course landing pages each have a 90-second preview video, 18 pages in total.

Last spring the site moved to a new theme, and GA4 `video_start` events dropped from about 600 a month to zero. The team assumed the new videos were worse. They spent two weeks reshooting one of them.

YouTube Studio told a different story. The playback location report (embedded in external websites) showed roughly 2,300 views over the same three months, flat.

The new theme used a click-to-play facade, a static thumbnail with a play button. No iframe exists until someone clicks.

When they do, the theme injects an iframe with `autoplay=1` and no `enablejsapi`. Enhanced measurement never had a player to talk to. The GTM trigger wouldn't have helped either, because no video and no IFrame API script were on the page when GTM loaded.

The fix took an hour. I switched off the theme's "load video on click" option, so the pages use a normal iframe with `loading="lazy"`, and ticked the API checkbox in the GTM trigger.

Her CMP already reloads the page after consent, so the iframe is there when GTM loads. She gave up a bit of page speed on those 18 pages. For her, worth it.

In the following month GA4 showed 2,140 `yt_start` events against about 2,280 embedded views in YouTube Studio. Close enough. The reshoot wasn't needed.

## How to set up YouTube video tracking in GA4 with GTM

### Step 1: Enable the built-in Video variables

Variables > Built-In Variables > Configure, then tick everything under **Videos**: Video Current Time, Video Duration, Video Percent, Video Provider, Video Status, Video Title, Video URL, Video Visible. They read keys like `gtm.videoPercent` that the trigger pushes. Without the trigger, they're empty. (The [GTM variables guide](https://piotrlitwa.com/articles/en/gtm-variables.html) explains why.)

### Step 2: Create the YouTube Video trigger

Triggers > New > Trigger Configuration > **YouTube Video**. Then:

1. **Capture**: tick Start, Complete and Progress. Leave "Pause, Seeking, and Buffering" off unless someone will actually read that data. It's noisy.

2. **Progress**: choose Percentages and enter `10, 25, 50, 75, 90`. I add 90 because plenty of people close a video during the end screen and never trigger Complete.

3. **Advanced**: tick **Add JavaScript API support to all YouTube videos**. GTM appends `enablejsapi=1` to the player URL. Google warns it reloads a video that's already playing when GTM loads, so watch autoplay hero videos.

4. **Enable this trigger on**: the default is Window Load. Google's March 2019 release notes recommend DOM Ready for YouTube triggers, while the help page tip (clearly copied from the scroll trigger) says Window Load. I use DOM Ready.

5. **This trigger fires on**: All Videos, or Some Videos with a condition like Video URL contains your channel's video IDs.

One detail from the docs worth knowing: thresholds fire only the first time they're reached. If someone drags the scrub bar from 5% to 80%, the 10, 25, 50 and 75% events don't fire.

### Step 3: Create the GA4 event tag

Tags > New > Google Analytics: GA4 Event. Event name: `yt_{{Video Status}}`. Video Status holds the action that fired the trigger, so you get `yt_start`, `yt_progress` and `yt_complete`. Check the exact values in Preview before you build reports on them.

Parameters:

- `video_title` = `{{Video Title}}`
- `video_url` = `{{Video URL}}`
- `video_percent` = `{{Video Percent}}`
- `video_current_time` = `{{Video Current Time}}`
- `video_duration` = `{{Video Duration}}`
- `video_provider` = `{{Video Provider}}`
- `visible` = `{{Video Visible}}`

I reuse Google's parameter names on purpose, so the built-in Video title and Video URL dimensions can pick them up. Confirm that in an Exploration before you trust it.

Why not just name the event `video_start`? Because Google's event naming rules list `video_start` and `video_progress` as reserved names for web streams. If you've read my piece on [how to track link clicks in GA4 with GTM](https://piotrlitwa.com/articles/en/track-link-clicks-ga4-gtm.html), it's the same lesson as with `click`.

### Step 4: Turn off the enhanced measurement toggle

If GTM owns video tracking, switch off Video engagement in enhanced measurement. Otherwise the same play shows up twice, as `video_start` and as `yt_start`.

## Duplicates: the report that showed more starts than visitors

Sebastian works for an industrial pump manufacturer in Bielsko-Biała. Their product pages carry 3-minute demo videos, and sales wanted to know who watched them. An agency set up the GTM trigger. Nobody touched the enhanced measurement toggle.

Three months later Sebastian's Looker Studio report showed 1,412 video starts a month on product pages that got 690 sessions. His filter was "event name contains start". It summed `video_start` from enhanced measurement and `yt_start` from GTM.

On top of that, every product page had a muted, autoplaying background clip at the top. It counted as a start for every visitor, and GTM's API checkbox reloaded it, which fired a second one.

Fix: toggle off, the background clip excluded with a Some Videos condition on its Video URL, and the report filter changed to an exact event name. Starts dropped to 655 a month. Lower, and finally believable.

I'll be blunt: if your video starts are higher than your sessions on the same pages, don't celebrate. Something fires twice.

## When tracking fails, and the EU consent problem

Here are the failure modes I see most, in one place:

| Symptom | Likely cause | Fix |
|---|---|---|
| Zero video events, ever | No `enablejsapi=1` in the iframe | Tick the GTM API checkbox, or add the parameter in the embed |
| Zero events on pages with thumbnails | Click-to-play facade creates the iframe late | Turn the facade off, or inject the iframe with `enablejsapi=1` and use a custom IFrame API listener |
| Events only after a page reload | CMP blocks the iframe, injects it after consent | Reload the page on consent, or use a custom IFrame API listener |
| Starts but no progress | Live stream, or viewers leave in the first seconds | Live streams have no fixed duration, so percentages mean nothing. Check Video Duration in Preview |
| Double starts | Toggle and GTM both on | Pick one owner |

Now the consent part, because in the EU it matters more than the tracking.

A YouTube embed isn't neutral. The moment the iframe loads, the visitor's browser talks to Google's servers.

That's why most CMPs, Cookiebot and similar tools included, block YouTube iframes until the visitor accepts a marketing or external media category. They swap the iframe for a placeholder and inject the real one after consent. For tracking, that's the same problem as a facade: the iframe appears after GTM has loaded.

**What about `youtube-nocookie.com`?** YouTube calls it privacy-enhanced mode. It cuts back cookies before playback, which is good. It does not make the embed consent-free. The browser still connects to Google on page load, and once the video plays, YouTube can store data in the browser. I treat nocookie embeds exactly like regular ones in the CMP. Whether your trigger picks up nocookie embeds is something to verify in Preview on your own site, not something to assume.

The GA4 side is separate. Your `yt_` events still respect Consent Mode. With `analytics_storage` denied, Basic mode sends nothing and Advanced mode sends cookieless pings. My [Consent Mode v2 guide](https://piotrlitwa.com/articles/en/consent-mode-v2-guide.html) covers the difference.

## Testing and registering the parameters

Open Preview and play a video. In the Tag Assistant event list you'll see YouTube Video events (in the data layer, `gtm.video`). Check three of them: start, one progress point, complete.

In the Variables tab, Video Status, Video Percent and Video Title should be filled. An empty Video Title usually means the API isn't connected yet.

Then GA4 Admin > DebugView. Your `yt_start` should arrive with all seven parameters. If it shows in Preview but not DebugView, consent is the first suspect. The [GA4 debug mode guide](https://piotrlitwa.com/articles/en/ga4-debug-mode.html) walks through the other usual causes.

Last, register what you'll report on. Admin > Data display > Custom definitions:

1. `video_percent` as an event-scoped custom dimension, so you can build a 10/25/50/75/90 drop-off table
2. `video_duration` and `video_current_time` as custom metrics, unit of measurement Seconds, if you want average watch time
3. Nothing else unless someone asks. A standard property has 50 event-scoped custom dimensions and they run out.

Data appears from the moment you register. Not retroactively.

## Frequently asked questions

**Does GA4 track YouTube videos automatically?**
Only if enhanced measurement's Video engagement toggle is on and the embed has JS API support, meaning `enablejsapi=1` in the iframe URL. Then GA4 sends `video_start`, `video_progress` at 10/25/50/75% and `video_complete`. Without the API parameter, nothing is tracked.

**Why is video_start not showing in GA4?**
The three usual causes: no `enablejsapi=1` on the embed, an iframe that's created after page load (facades, CMP placeholders), or consent blocking the GA4 tag. Check the iframe `src` first, then Preview, then consent.

**Can I track YouTube videos that load after the page loads?**
With GTM, yes, as long as at least one YouTube video or the YouTube IFrame API script is on the page when GTM loads. If neither is there, late videos are missed. A page reload after consent or a custom IFrame API listener solves it.

**Should I use enhanced measurement or GTM for video tracking?**
GTM, if video views matter to your business. You choose the thresholds, event names and which videos to track, and every change is versioned. Use enhanced measurement only for simple sites, and never both for the same videos.

**Is youtube-nocookie.com GDPR-compliant without consent?**
I wouldn't rely on it. Privacy-enhanced mode reduces cookies before playback, but the browser still connects to Google servers on load, and data can be stored once the video plays. Treat it like a normal YouTube embed in your CMP.

**Can I track Vimeo videos with the same trigger?**
No. The GTM YouTube Video trigger only handles YouTube. Vimeo needs its own player API listener, usually from a community template in the Template Gallery.

## Next steps

Open one of your pages with a video and inspect the iframe. No `enablejsapi=1` in the `src`? Then enhanced measurement has reported zero plays for that embed since the day it went live, whatever the toggle says.

Then decide who owns video tracking, GTM or the toggle, and switch the other one off. Build the trigger, test start, progress and complete in Preview, and register `video_percent` today so next month's report has a drop-off curve.

If you'd like someone to check your video, consent and enhanced measurement setup in one pass, the [free GTM audit](https://piotrlitwa.com/checkGTM/) does exactly that. For ongoing GA4 checks that notice when a theme update kills your video events, see [GA4 monitoring](https://piotrlitwa.com/services.html#ga4).

---

**Sources and further reading**
- [Enhanced measurement events](https://support.google.com/analytics/answer/9216061) (Google Analytics Help)
- [YouTube video trigger](https://support.google.com/tagmanager/answer/7679325) (Tag Manager Help)
- [YouTube embedded player parameters: enablejsapi](https://developers.google.com/youtube/player_parameters#enablejsapi) (YouTube for Developers)
- [Event naming rules](https://support.google.com/analytics/answer/13316687) (Google Analytics Help)

---

*Written by [Piotr Litwa](https://piotrlitwa.com/about.html) - independent GTM & Analytics specialist.*
