Skip to main content

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.

vimeovideogtmga4content-marketingengagement

Event fired

vimeoTrack

Key variable

videoAction

Vimeo

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

mermaid
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

html
<!-- 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

json
{
  "event": "vimeoTrack",
  "attributes": {
    "videoAction": "play",
    "videoName": "Product Demo 2024"
  }
}

Progress Milestone

json
{
  "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 NameDL KeyExample
DLV – Vimeo Actionattributes.videoAction"play"
DLV – Vimeo Titleattributes.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 EventParameterValue
video_startvideo_titleDLV – Vimeo Title
video_startvideo_provider"vimeo"
video_progressvideo_percentDLV – Vimeo Action
video_completevideo_titleDLV – Vimeo Title

Use GTM's event condition to map different videoAction values to different GA4 events:

  • playvideo_start
  • 25%, 50%, 75%video_progress
  • watch to endvideo_complete

Debugging

ProblemCauseFix
No events firingVimeo iframe blocked by CSPCheck Content-Security-Policy header
videoName is emptyVideo is privateUse video ID as fallback
Events fire multiple timesMultiple listenersEnsure single GTM container
Percentage milestones skippedtimeupdate frequencyReduce precision to 25% intervals

Best Practices

  1. Exclude 10% milestone for conversion tracking, use 75% or "watch to end"
  2. Debounce play events, some players fire play multiple times on seek
  3. Combine with page context, include {{Page Path}} to know which page the video was on
  4. Test on playlist pages, pages with multiple Vimeo iframes all get tracked

Related Listeners

  • Wistia, Marketing-optimized video with chapter tracking
  • Vidyard, Sales video engagement tracking
  • Calendly, Often placed alongside demo videos