# 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](https://videojs.org/docs/framework/react/guides/architecture) 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:

```bash
pnpm add @videojs/react @videojs/google-analytics
```

**App.tsx**

```tsx
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.

> **Note**
>
> Google Analytics tracking is opt-in. No media component sends telemetry on its own until you add the extension to 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`:

```js
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`:

```tsx
<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):

```tsx
<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`.

```tsx
<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`):

```tsx
<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:

```tsx
<GoogleAnalytics debug />
```

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

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

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

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

## Related pages

### Components

- [GoogleAnalytics](https://videojs.org/docs/framework/react/reference/components/google-analytics): Options for the Google Analytics 4 extension that tracks video engagement and playback events
- [MuxData](https://videojs.org/docs/framework/react/reference/components/mux-data): Options for the Mux Data extension that monitors playback quality

### Guides

- [Monitor playback with Mux Data](https://videojs.org/docs/framework/react/guides/mux-data): Measure startup time, rebuffering, failures, and watch time by adding the Mux Data extension to a player

---

React documentation: https://videojs.org/docs/framework/react/llms.txt
All documentation: https://videojs.org/llms.txt
