Skip to content

Instantly share code, notes, and snippets.

@tusharsnx
Last active October 14, 2024 12:14
Show Gist options
  • Save tusharsnx/201b71990f93d6da0995c422f339f97d to your computer and use it in GitHub Desktop.
Save tusharsnx/201b71990f93d6da0995c422f339f97d to your computer and use it in GitHub Desktop.
React hook to add embedded Youtube player
import { useState, useEffect } from "react";
class YTPlayer {}
export enum YTPlayerState {
UNSTARTED = -1,
ENDED = 0,
PLAYING = 1,
PAUSED = 2,
BUFFERING = 3,
CUED = 5,
}
interface YoutubeAPI {
Player: YTPlayer;
PlayerState: YTPlayerState;
}
declare global {
namespace globalThis {
var onYouTubeIframeAPIReady: () => void;
var youtubeIframeAPIReady: boolean;
var youtubeIframeListeners: (() => void)[] | undefined;
var YT: YoutubeAPI;
}
}
export default function useYoutubeAPI() {
const [isAPILoaded, setIsAPILoaded] = useState(globalThis.youtubeIframeAPIReady);
const [ytAPI, setYTAPI] = useState<YoutubeAPI | undefined>(undefined);
if (isAPILoaded && !ytAPI) {
setYTAPI(globalThis.YT);
}
useEffect(() => {
// FixMe: Don't add to listeners list if api is already loaded
globalThis.youtubeIframeListeners ??= [];
const handler = () => setIsAPILoaded(true);
globalThis.youtubeIframeListeners.push(handler);
if (!globalThis.onYouTubeIframeAPIReady) {
// Dynamically load YouTube API on client side
const tag = document.createElement("script");
tag.src = "https://www.youtube.com/iframe_api";
const firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode?.insertBefore(tag, firstScriptTag);
// YouTube API will call this function when ready
globalThis.onYouTubeIframeAPIReady = () => {
globalThis.youtubeIframeAPIReady = true;
if (globalThis.youtubeIframeListeners) {
for (const listener of globalThis.youtubeIframeListeners) {
listener();
}
}
};
return;
}
return () => {
globalThis.youtubeIframeListeners?.splice(globalThis.youtubeIframeListeners.indexOf(handler), 1);
};
}, []);
return ytAPI;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment