Skip to content

GuidePlayback

Track video telemetry with Google Analytics 4

Track video engagement, progress milestones, and playback interactions by adding the Google Analytics extension to a player

Google Analytics 4 (GA4) Enhanced Measurement tracks video engagement and viewer interaction. Add the Google Analytics extension to a player and it monitors whichever media that player is playing, automatically dispatching standard GA4 Enhanced Measurement video events and playback interaction events to window.dataLayer and window.gtag.

Install the extension alongside the framework façade:

pnpm add @videojs/react @videojs/google-analytics
import { Container, createPlayer } from '@videojs/react';
import { GoogleAnalytics } from '@videojs/react/extensions/google-analytics';
import { Video } from '@videojs/react/media/video';
import { videoFeatures } from '@videojs/react/video';

const { Player } = createPlayer({ features: videoFeatures });

export default function App() {
  return (
    <Player>
      <Container>
        <Video src="https://example.com/video.mp4" />
        <GoogleAnalytics metadata={{ video_title: 'My Video' }} />
      </Container>
    </Player>
  );
}

That’s the entire setup for standard video tracking. The extension renders nothing; place it anywhere inside the player.

How events are reported

When Google Tag (gtag.js) or Google Tag Manager (GTM) is configured on your site, window.dataLayer is available globally. The extension pushes structured event objects into window.dataLayer:

window.dataLayer.push({
  event: 'video_progress',
  video_current_time: 30,
  video_duration: 120,
  video_percent: 25,
  video_provider: 'video.js',
  video_stream_type: 'on-demand',
  video_title: 'My Video',
  video_url: 'https://example.com/video.mp4',
  visible: true,
});

If window.gtag is defined, the extension also calls window.gtag('event', event, params) with the same parameters. If you use a custom data layer array on window, specify its property name with dataLayerName (or data-layer-name in HTML).

GA4 Enhanced Measurement events

The extension dispatches standard GA4 Enhanced Measurement video events:

  • video_start: Dispatched when playback begins for the first time or starts at currentTime > 0.
  • video_progress: Dispatched when playback crosses 10%, 25%, 50%, and 75% milestones.
  • video_complete: Dispatched when the video reaches the end (ended event) or loops back to the start.

Video.js interaction events

In addition to GA4 Enhanced Measurement events, the extension emits player interaction events to measure how viewers engage with controls:

  • play: Dispatched on first play.
  • pause: Dispatched when playback is paused (not triggered during seeking or when ended).
  • resume: Dispatched when playback resumes after a pause.
  • end: Dispatched when the video finishes.
  • seek: Dispatched when scrubbing or seeking completes (bypassed on loop restarts).
  • mute: Dispatched when audio is muted or volume drops to 0.
  • unmute: Dispatched when audio is unmuted with non-zero volume.
  • fullscreenEnter: Dispatched when entering fullscreen.
  • fullscreenExit: Dispatched when exiting fullscreen.

Set stream type

By default, the stream type is inferred from the media (media.streamType === 'live' ? 'live' : 'on-demand'). For on-demand videos, duration is known and the extension calculates playback percentage to fire progress milestones at 10%, 25%, 50%, and 75%.

To override or explicitly specify a live stream, pass video_stream_type: 'live' in metadata:

<GoogleAnalytics metadata={{ video_title: 'Live Stream', video_stream_type: 'live' }} />

When the effective stream type is 'live', milestone progress tracking is bypassed since live streams have unbounded or dynamic duration.

Disable progress tracking

By default, the extension tracks progress milestones at 10%, 25%, 50%, and 75% for on-demand playback. To turn off milestone progress tracking, set disableProgress (or disable-progress in HTML):

<GoogleAnalytics disableProgress />

Set video title

Set metadata.video_title on the extension so GA4 gets an explicit title for every media type, including iframe embeds that do not expose a useful DOM title.

<GoogleAnalytics metadata={{ video_title: 'Keynote Presentation' }} />

When metadata.video_title is omitted, the extension derives a title in this order: the title the media reports in its content data (Mux, Vimeo, and SoundCloud media report one, for example), then the resolved video_url, then 'Untitled Video'. Do not rely on a <video title="..."> attribute as your analytics title; set metadata.video_title instead.

Metadata and custom dimensions

Pass metadata to set official GA4 video parameters (video_title, video_provider, video_url) and custom dimensions (such as Mux Data compatible names video_id, video_series, video_producer, video_content_type, or custom dimensions like custom_1):

<GoogleAnalytics
  metadata={{
    video_title: 'Keynote Presentation',
    video_series: 'Annual Conference',
    video_producer: 'Video.js Team',
    video_id: 'conf_2026_01',
    custom_1: 'attendee_pro',
  }}
/>

GA4 collection limits

Google Analytics 4 enforces collection limits on event parameters:

  • 25 parameters per event: The extension sends 8 standard parameters (video_current_time, video_duration, video_percent, video_provider, video_stream_type, video_title, video_url, and visible), leaving room for up to 17 custom dimensions in metadata.
  • Parameter names: Up to 40 characters in length.
  • String values: Up to 100 characters in length.

Debugging

Enable console logging by setting the debug option:

<GoogleAnalytics debug />

When enabled, the extension logs every dispatched event and its parameters:

[GoogleAnalyticsExtension] Event: "video_start" {video_current_time: 0, video_duration: 120, ...}

You can also provide an onEvent callback to intercept dispatched events programmatically:

<GoogleAnalytics
  onEvent={(event, params) => {
    console.log('Telemetry event:', event, params);
  }}
/>

Components

Guides