Vimeo GTM Event Listener
Track Vimeo video interactions in GTM. Monitor play, pause, and watch-to-end events with videoAction and videoName variables. Fire GA4 video tracking events.
Event fired
vimeoTrackKey variable
videoActionVimeo
Overview
Vimeo is a professional video hosting platform widely used for marketing and educational content. This listener uses Vimeo's Player SDK to track play, pause, progress milestones (25%, 50%, 75%, 90%, 100%), and watch-to-end events for all embedded Vimeo iframes on the page.
Event fired: vimeoTrack
Variables: videoAction, videoName
Credit: Bounteous (original script)
Why Use This Listener
Video engagement is one of the strongest proxies for content interest. Vimeo iframes don't expose events to the parent page without the Vimeo Player API. This listener loads the API dynamically and attaches event handlers to every Vimeo player on the page.
Common Use Cases
- Track video completion rates as GA4 engagement events
- Use video watch percentage as a lead scoring signal
- Fire Google Ads remarketing tags on 75%+ video views
- Identify which videos drive the highest conversion rates
- Build audiences of users who watched product demos
How It Works
flowchart TD
A[Page loads with Vimeo iframe] --> B[Listener script runs]
B --> C[Detects player.vimeo.com iframes]
C --> D[Loads Vimeo Player SDK]
D --> E[Attaches play/pause/timeupdate listeners]
E --> F{User Interaction}
F -->|Play| G[push vimeoTrack play]
F -->|25% milestone| H[push vimeoTrack 25%]
F -->|Pause| I[push vimeoTrack pause]
F -->|End| J[push vimeoTrack watch to end]Installation
<!-- GTM Custom HTML Tag: Vimeo Video Listener -->
<!-- Trigger: DOM Ready -->
<script>
(function() {
var VimeoPlayer = [];
var percentages = [0.1, 0.25, 0.5, 0.75, 0.9, 1];
function loadVimeoAPI(callback) {
if (window.Vimeo) { callback(); return; }
var script = document.createElement('script');
script.src = 'https://player.vimeo.com/api/player.js';
script.onload = callback;
document.head.appendChild(script);
}
function pushVimeoEvent(action, title) {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'vimeoTrack',
'attributes': {
'videoAction': action,
'videoName': title
}
});
}
function initPlayers() {
var iframes = document.querySelectorAll('iframe[src*="player.vimeo.com/video/"]');
if (!iframes.length) return;
iframes.forEach(function(iframe) {
var player = new Vimeo.Player(iframe);
var tracked = { play: false, percentages: {} };
player.getVideoTitle().then(function(title) {
player.on('play', function() {
if (!tracked.play) {
tracked.play = true;
pushVimeoEvent('play', title);
}
});
player.on('pause', function() {
tracked.play = false;
pushVimeoEvent('pause', title);
});
player.on('ended', function() {
pushVimeoEvent('watch to end', title);
});
player.on('timeupdate', function(data) {
var percent = data.percent;
percentages.forEach(function(p) {
if (percent >= p && !tracked.percentages[p]) {
tracked.percentages[p] = true;
pushVimeoEvent(Math.round(p * 100) + '%', title);
}
});
});
});
});
}
loadVimeoAPI(initPlayers);
})();
</script>Data Layer Output
Play Event
{
"event": "vimeoTrack",
"attributes": {
"videoAction": "play",
"videoName": "Product Demo 2024"
}
}Progress Milestone
{
"event": "vimeoTrack",
"attributes": {
"videoAction": "75%",
"videoName": "Product Demo 2024"
}
}Trigger Configuration
All Vimeo Events
Trigger Type: Custom Event
Event Name: vimeoTrack
Specific Actions (using regex)
Condition: DLV – Vimeo Action | matches RegEx | (play|watch to end|75%)
Variables to Capture
| Variable Name | DL Key | Example |
|---|---|---|
| DLV – Vimeo Action | attributes.videoAction | "play" |
| DLV – Vimeo Title | attributes.videoName | "Product Demo 2024" |
Use dot-notation in the Data Layer Variable:
attributes.videoAction
GA4 Mapping Recommendations
Map to GA4's recommended video event schema:
| GA4 Event | Parameter | Value |
|---|---|---|
video_start | video_title | DLV – Vimeo Title |
video_start | video_provider | "vimeo" |
video_progress | video_percent | DLV – Vimeo Action |
video_complete | video_title | DLV – Vimeo Title |
Use GTM's event condition to map different videoAction values to different GA4 events:
play→video_start25%,50%,75%→video_progresswatch to end→video_complete
Debugging
| Problem | Cause | Fix |
|---|---|---|
| No events firing | Vimeo iframe blocked by CSP | Check Content-Security-Policy header |
videoName is empty | Video is private | Use video ID as fallback |
| Events fire multiple times | Multiple listeners | Ensure single GTM container |
| Percentage milestones skipped | timeupdate frequency | Reduce precision to 25% intervals |
Best Practices
- Exclude 10% milestone for conversion tracking, use 75% or "watch to end"
- Debounce play events, some players fire play multiple times on seek
- Combine with page context, include
{{Page Path}}to know which page the video was on - Test on playlist pages, pages with multiple Vimeo iframes all get tracked