Last active
October 14, 2024 12:14
-
-
Save tusharsnx/201b71990f93d6da0995c422f339f97d to your computer and use it in GitHub Desktop.
React hook to add embedded Youtube player
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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