Handling Events

useYouTubeEvent supports both reactive state subscriptions and callback-style side effects.

1. State-style subscriptions

Use this when your UI should re-render with the latest value.

const playbackRate = useYouTubeEvent(player, 'playbackRateChange', 1);
const isMuted = useYouTubeEvent(player, 'muteChange', false);
const progress = useYouTubeEvent(player, 'progress', 1000);

2. Callback-style subscriptions

Use this for side effects, analytics, toasts, logging, or one-off app reactions.

useYouTubeEvent(player, 'ready', (playerInfo) => {
  console.log('ready', playerInfo);
});

useYouTubeEvent(player, 'error', (error) => {
  console.error(error);
});

useYouTubeEvent(player, 'autoplayBlocked', () => {
  console.log('autoplay blocked');
});

Optional dependency array for callbacks

If your callback depends on changing values, pass a dependency array as the fourth argument.

useYouTubeEvent(
  player,
  'stateChange',
  (state) => {
    console.log('state', state, analyticsLabel);
  },
  [analyticsLabel],
);

Event list

EventPayloadNotes
readyPlayerInfoFirst full player snapshot
stateChangePlayerStateUNSTARTED, PLAYING, PAUSED, BUFFERING, ENDED, CUED
errorYoutubeErrorYouTube or bridge-level error
progressProgressDatacurrentTime, duration, percentage, loadedFraction
playbackRateChangenumberCurrent playback speed
playbackQualityChangePlaybackQualityCurrent quality level
autoplayBlockedundefinedBrowser/platform autoplay restriction
muteChangebooleanCurrent muted state

ready payload

ready provides a rich initial snapshot:

  • availablePlaybackRates
  • availableQualityLevels
  • currentTime
  • duration
  • muted
  • playbackQuality
  • playbackRate
  • playerState
  • size
  • volume

progress payload

progress includes:

{
  currentTime: number;
  duration: number;
  percentage: number;
  loadedFraction: number;
}

Progress interval behavior

progress is special:

  • third argument = polling interval in milliseconds
  • default = 1000
  • pass 0 if you do not want interval-based progress updates
const progress = useYouTubeEvent(player, 'progress', 500);

The bridge also refreshes progress shortly after seekTo() so the UI catches up quickly after manual seeking.

Mute tracking nuance

Muted state tracking is enabled only while muteChange is subscribed. This keeps the feature user-friendly without paying the tracking cost when the app does not need it.