
GA4 tracks embedded YouTube videos automatically through enhanced measurement: with “Video engagement” switched on, it sends video_start, video_progress (at 10%, 25%, 50% and 75%) and video_complete, as long as the embed has YouTube’s JavaScript API enabled. For Vimeo, self-hosted HTML5 video, other players or custom milestones, you need Google Tag Manager: a trigger or a small listener script sends the events, and a GA4 event tag passes them on.
Below is the setup for both routes, how to get video data into reports, and how to test it.
What can GA4 tell you about video on your website?
Once tracking works, GA4 answers the questions that decide whether a video earns its place on the page:
- How many visitors start the video, and how far they get before dropping off.
- Which videos are watched to the end, by traffic source, device and landing page.
- Whether people who watch go on to a key event (a demo request, a purchase, a sign-up) more often than people who don’t.
That last one is the point. A video with modest views that lifts demo requests is worth more than a popular one that changes nothing.
How do you turn on built-in YouTube tracking in GA4?
- In GA4, go to Admin → Data streams and open your web stream.
- Under Enhanced measurement, click the gear icon and make sure Video engagement is on.
- Make sure each YouTube embed has the JavaScript API enabled: the iframe’s
srcmust includeenablejsapi=1, for examplehttps://www.youtube.com/embed/VIDEO_ID?enablejsapi=1. Without it, GA4 can’t listen to the player and nothing is sent.
GA4 then sends these events and parameters:
| Event | When it fires | Parameters |
|---|---|---|
video_start |
The video starts playing | video_current_time, video_duration, video_percent, video_provider, video_title, video_url, visible |
video_progress |
Playback passes 10%, 25%, 50% and 75% | Same as above |
video_complete |
The video reaches the end | Same as above |
Built-in tracking covers YouTube only. Players injected after the page loads (lazy-loaded embeds, pop-ups, sliders) are a common source of missing events, so test those pages specifically.
How do you track YouTube videos with Google Tag Manager instead?
Use GTM when you want pause and seek events, different milestones, or one consistent setup across all video players.
- Avoid duplicates. Turn off Video engagement in GA4’s enhanced measurement first, or every event will be counted twice.
- Enable the built-in video variables. In GTM, go to Variables → Configure and tick Video Provider, Video Status, Video URL, Video Title, Video Duration, Video Percent, Video Current Time and Video Visible.
- Create the trigger. New trigger → YouTube Video. Choose Start, Complete, Progress (for example 25, 50, 75 percent) and, if you want them, Pause, Seeking and Buffering. Tick “Add JavaScript API support to all YouTube videos” so you don’t depend on the embed code.
- Create the tag. New tag → Google Analytics: GA4 Event. Set the event name to
video_{{Video Status}}, which producesvideo_start,video_progress,video_completeand so on. Add parameters:video_title={{Video Title}},video_url={{Video URL}},video_percent={{Video Percent}},video_provider={{Video Provider}},video_duration={{Video Duration}}. - Test in GTM Preview and GA4 DebugView (see below), then publish.
How do you track Vimeo, HTML5 and other video players?
Other players don’t fire GTM’s YouTube trigger, so you listen to the player’s own events and push them to the data layer.
- Self-hosted HTML5 video (
<video>tags): listen forplay,timeupdateandended. - Vimeo: use the Vimeo Player API (player.js), which exposes play, progress and ended events.
- Wistia, Vidyard and similar hosts: use their JavaScript API; some offer their own GA4 integration, which is worth checking first.
A minimal listener for HTML5 video, added in GTM as a Custom HTML tag that fires on DOM Ready:
<script>
(function () {
var marks = [25, 50, 75];
document.querySelectorAll('video').forEach(function (v) {
var sent = {};
function push(action, pct) {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'video_' + action,
video_provider: 'html5',
video_title: v.getAttribute('title') || (v.currentSrc || '').split('/').pop(),
video_url: v.currentSrc,
video_percent: pct
});
}
v.addEventListener('play', function () {
if (!sent.start) { sent.start = true; push('start', 0); }
});
v.addEventListener('timeupdate', function () {
if (!v.duration) return;
var pct = Math.floor(v.currentTime / v.duration * 100);
marks.forEach(function (m) {
if (pct >= m && !sent[m]) { sent[m] = true; push('progress', m); }
});
});
v.addEventListener('ended', function () { push('complete', 100); });
});
})();
</script>
Then create a Custom Event trigger matching the regex ^video_(start|progress|complete)$, Data Layer Variables for video_title, video_url, video_percent and video_provider, and a GA4 Event tag with the event name {{Event}} and those parameters. Using the same event names as GA4’s built-in tracking keeps all players in one report.
How do you report on video in GA4?
- Register what you need as custom dimensions. GA4 includes some video dimensions out of the box (such as video title, provider and URL). Parameters like
video_percentonly show up in reports after you register them under Admin → Custom definitions as event-scoped dimensions. Registration isn’t retroactive, so do it early. - Build a funnel in Explorations.
video_start→video_progresswithvideo_percent= 50 →video_complete→ your key event. This shows where viewers drop off and whether finishers convert. - Compare viewers with non-viewers. Create a segment of users with a
video_startevent and compare their key-event rate with everyone else’s on the same pages. - Mark a video event as a key event only if it is a real goal, for example finishing a product demo. Most video events are diagnostics, not outcomes.
For teams that live in dashboards, the same events feed Looker Studio. On TMT Finance, for example, we track 90+ data points across GTM and GA4 and report them in Looker Studio dashboards (the TMT Finance case). For the event model behind all of this, see our guide to GA4 event tracking.
What about images, 360° views and other rich media?
The same pattern works for any visual interaction your site cares about: push a data layer event when it happens, then send it to GA4 with a few parameters. Keep the list short and tied to a question you actually want answered.
| Interaction | Example event name | Useful parameters |
|---|---|---|
| Product image click or zoom | image_interaction |
image_id, interaction_type (click, zoom, swipe), product_id |
| Interactive 360° product view | view_360 |
product_id, interaction_count |
| AR or “view in your room” launch | ar_start |
product_id, ar_mode |
How do you test video tracking?
- Open GTM Preview (Tag Assistant), play a video, and check that the right tag fires at start, at each milestone and at the end.
- In GA4, open Admin → DebugView and confirm the events arrive with their parameters.
- Check Realtime for a quick sanity check, then wait a day before reading standard reports.
If tracking still looks wrong, our GTM and GA4 debugging workflow walks through the usual suspects.
FAQ
Why are my GA4 video events not showing up?
The usual causes: Video engagement is off in enhanced measurement, the YouTube embed lacks enablejsapi=1, the player loads after the page, consent hasn’t been granted for analytics, or the video isn’t on YouTube at all. DebugView tells you which.
Does GA4 track Vimeo videos automatically?
No. Built-in video tracking covers embedded YouTube videos only. Vimeo and other players need a listener in Google Tag Manager, as described above.
Can GA4 track views of my videos on YouTube.com itself?
No. GA4 measures your website. Views on YouTube are reported in YouTube Studio’s analytics.
Should video completion be a key event?
Only when finishing the video is a business goal, such as a product demo before a sales call. Otherwise keep video events as engagement signals and judge the video by the key events that follow it.
Need video and event tracking set up properly? Our GA4 team and Google Tag Manager specialists can help; get in touch.


