Events & Callbacks
Learn how to handle video events and track user interactions with React Lite YouTube Embed.
onIframeAdded Callback
The onIframeAdded callback is triggered when the user clicks the thumbnail and the real YouTube iframe is added to the DOM.
Basic Usage
Track when video starts
import LiteYouTubeEmbed from 'react-lite-youtube-embed';
export default function VideoWithCallback() {
const handleIframeAdded = () => {
console.log('User started watching video');
};
return (
<LiteYouTubeEmbed
id="dQw4w9WgXcQ"
title="Video"
onIframeAdded={handleIframeAdded}
/>
);
}
Analytics Integration
Google Analytics
Track video plays with Google Analytics:
Google Analytics tracking
import LiteYouTubeEmbed from 'react-lite-youtube-embed';
export default function TrackedVideo({ videoId, title }) {
const handleVideoPlay = () => {
// GA4
gtag('event', 'video_start', {
video_id: videoId,
video_title: title
});
};
return (
<LiteYouTubeEmbed
id={videoId}
title={title}
onIframeAdded={handleVideoPlay}
/>
);
}
Segment
Segment tracking
import { useAnalytics } from '@segment/analytics-react';
export default function SegmentVideo({ videoId, title }) {
const analytics = useAnalytics();
const handleVideoPlay = () => {
analytics.track('Video Played', {
video_id: videoId,
video_title: title,
player_type: 'lite-youtube-embed'
});
};
return (
<LiteYouTubeEmbed
id={videoId}
title={title}
onIframeAdded={handleVideoPlay}
/>
);
}
Plausible Analytics
Plausible tracking
declare global {
interface Window {
plausible?: (event: string, options?: any) => void;
}
}
export default function PlausibleVideo({ videoId, title }) {
const handleVideoPlay = () => {
window.plausible?.('Video Play', {
props: {
video_id: videoId,
video_title: title
}
});
};
return (
<LiteYouTubeEmbed
id={videoId}
title={title}
onIframeAdded={handleVideoPlay}
/>
);
}
State Management
Track Play Count
Count video plays
import { useState } from 'react';
import LiteYouTubeEmbed from 'react-lite-youtube-embed';
export default function PlayCountVideo() {
const [playCount, setPlayCount] = useState(0);
return (
<div>
<LiteYouTubeEmbed
id="VIDEO_ID"
title="Video"
onIframeAdded={() => setPlayCount(prev => prev + 1)}
/>
<p>Played {playCount} times</p>
</div>
);
}
Track Multiple Videos
Track which videos are playing
import { useState } from 'react';
export default function MultipleVideos() {
const [playingVideos, setPlayingVideos] = useState<Set<string>>(new Set());
const handleVideoPlay = (videoId: string) => {
setPlayingVideos(prev => new Set(prev).add(videoId));
};
const videos = [
{ id: 'video1', title: 'Video 1' },
{ id: 'video2', title: 'Video 2' },
{ id: 'video3', title: 'Video 3' }
];
return (
<div>
<p>{playingVideos.size} videos have been played</p>
<div className="video-grid">
{videos.map((video) => (
<LiteYouTubeEmbed
key={video.id}
id={video.id}
title={video.title}
onIframeAdded={() => handleVideoPlay(video.id)}
/>
))}
</div>
</div>
);
}
Engagement Tracking
Time-Based Tracking
Track when users engage with videos:
Engagement timestamp tracking
import { useState } from 'react';
interface VideoEngagement {
videoId: string;
timestamp: Date;
}
export default function EngagementTracking() {
const [engagements, setEngagements] = useState<VideoEngagement[]>([]);
const handleVideoPlay = (videoId: string) => {
const engagement: VideoEngagement = {
videoId,
timestamp: new Date()
};
setEngagements(prev => [...prev, engagement]);
// Send to your backend
fetch('/api/video-engagement', {
method: 'POST',
body: JSON.stringify(engagement)
});
};
return (
<LiteYouTubeEmbed
id="VIDEO_ID"
title="Video"
onIframeAdded={() => handleVideoPlay('VIDEO_ID')}
/>
);
}
User Journey Tracking
Track video position in user journey
import { useEffect, useState } from 'react';
export default function JourneyTracking() {
const [videoOrder, setVideoOrder] = useState<string[]>([]);
const handleVideoPlay = (videoId: string) => {
setVideoOrder(prev => [...prev, videoId]);
};
useEffect(() => {
// Log when user watches videos in sequence
if (videoOrder.length > 0) {
console.log('User journey:', videoOrder);
}
}, [videoOrder]);
return (
<div>
<h2>Tutorial Series</h2>
<LiteYouTubeEmbed
id="tutorial-1"
title="Part 1"
onIframeAdded={() => handleVideoPlay('tutorial-1')}
/>
<LiteYouTubeEmbed
id="tutorial-2"
title="Part 2"
onIframeAdded={() => handleVideoPlay('tutorial-2')}
/>
<LiteYouTubeEmbed
id="tutorial-3"
title="Part 3"
onIframeAdded={() => handleVideoPlay('tutorial-3')}
/>
</div>
);
}
A/B Testing
Track Conversion by Video
A/B test video effectiveness
import { useState, useEffect } from 'react';
export default function ABTestVideo() {
const [variant, setVariant] = useState<'A' | 'B'>('A');
const [conversions, setConversions] = useState({ A: 0, B: 0 });
useEffect(() => {
// Randomly assign variant
setVariant(Math.random() > 0.5 ? 'A' : 'B');
}, []);
const handleVideoPlay = () => {
// Track that user watched video in this variant
analytics.track('Video Played', {
variant,
video_id: variant === 'A' ? 'VIDEO_A' : 'VIDEO_B'
});
};
return (
<LiteYouTubeEmbed
id={variant === 'A' ? 'VIDEO_A' : 'VIDEO_B'}
title={variant === 'A' ? 'Product Demo A' : 'Product Demo B'}
onIframeAdded={handleVideoPlay}
/>
);
}
Performance Monitoring
Load Time Tracking
Measure iframe load time
import { useState } from 'react';
export default function PerformanceTracking() {
const [loadTime, setLoadTime] = useState<number | null>(null);
const handleVideoPlay = () => {
const startTime = performance.now();
// Track iframe load completion
const checkIframe = setInterval(() => {
const iframe = document.querySelector('iframe');
if (iframe) {
const endTime = performance.now();
const duration = endTime - startTime;
setLoadTime(duration);
clearInterval(checkIframe);
// Send to analytics
analytics.track('Video Load Time', {
duration_ms: duration
});
}
}, 100);
};
return (
<div>
<LiteYouTubeEmbed
id="VIDEO_ID"
title="Video"
onIframeAdded={handleVideoPlay}
/>
{loadTime && <p>Loaded in {loadTime.toFixed(0)}ms</p>}
</div>
);
}
Error Tracking
Track Failed Loads
Track video load failures
import { useState, useEffect } from 'react';
export default function ErrorTracking() {
const [hasError, setHasError] = useState(false);
const handleVideoPlay = () => {
// Monitor for iframe errors
setTimeout(() => {
const iframe = document.querySelector('iframe');
if (!iframe) {
setHasError(true);
// Report to error tracking service
errorTracker.captureMessage('YouTube iframe failed to load', {
video_id: 'VIDEO_ID'
});
}
}, 5000);
};
return (
<div>
<LiteYouTubeEmbed
id="VIDEO_ID"
title="Video"
onIframeAdded={handleVideoPlay}
/>
{hasError && (
<div className="error">
Failed to load video. Please try again.
</div>
)}
</div>
);
}
Callback Best Practices
Use useCallback
Prevent unnecessary re-renders:
Memoize callback with useCallback
import { useCallback } from 'react';
export default function OptimizedCallback() {
const handleVideoPlay = useCallback(() => {
analytics.track('Video Played');
}, []); // Empty deps - callback never changes
return (
<LiteYouTubeEmbed
id="VIDEO_ID"
title="Video"
onIframeAdded={handleVideoPlay}
/>
);
}
Debounce Multiple Calls
Prevent duplicate tracking if component re-renders:
Debounce callback
import { useRef, useCallback } from 'react';
export default function DebouncedCallback() {
const hasTracked = useRef(false);
const handleVideoPlay = useCallback(() => {
if (!hasTracked.current) {
hasTracked.current = true;
analytics.track('Video Played');
}
}, []);
return (
<LiteYouTubeEmbed
id="VIDEO_ID"
title="Video"
onIframeAdded={handleVideoPlay}
/>
);
}
What onIframeAdded Does NOT Track
The onIframeAdded callback fires when:
- ✅ User clicks the thumbnail
- ✅ iframe is added to DOM
It does NOT fire for:
- ❌ When video actually starts playing
- ❌ When video is paused
- ❌ When video ends
- ❌ Video progress/time updates
YouTube Player API
For detailed playback events (play, pause, end, etc.), use the YouTube Player API with enableJsApi={true}.
Next Steps
- API Reference - Complete props documentation
- Examples - More callback patterns
- Performance - Optimize with callbacks