Quantcast
Channel: Active questions tagged youtube-api - Stack Overflow
Viewing all articles
Browse latest Browse all 3723

Persisting YT iframe player when changing routes in nextJS 14

$
0
0

I have a server component which loads info about a user video, like so

const MyPage = async() => {  const user: SessionUser = (await requireAuth(false)) as SessionUser;  const currentVideo = await getCurrentLeadershipMinuteVideo(user.id);  return (<div><Script src="https://www.youtube.com/iframe_api"></Script>      {!currentVideo ? (<p>There is no Video available at this time</p>      ) : (<VideoPlayer currentVideo={currentVideo} />      )}</div>  );}

My client component renders the iframe using the link from the server component.

const VideoPlayer = (props: LeadershipMinuteVideoProps) => {  const { currentVideo } = props;  const link = currentVideo.link as string;  const title = currentVideo.title as string;  const iframeRef = useRef<HTMLIFrameElement | null>(null);  const playerRef = useRef<any>(null);  const [isPlaying, setIsPlaying] = useState<boolean>(false);  const pauseVideo = () => {    playerRef.current.pauseVideo();  };  const playVideo = (): boolean => { // returns false if I remove destroy() function    if (playerRef.current && playerRef.current.playVideo) {      playerRef.current.playVideo();      return true;    }    return false;  };  const onPlayerStateChange = (event: any) => {    if (event.data === window.YT.PlayerState.PLAYING) {      //...    }  };  useEffect(() => {    const onYouTubeIframeAPIReady = () => {      if (iframeRef.current) {        playerRef.current = new window.YT.Player(iframeRef.current, {          events: {            onStateChange: onPlayerStateChange,          },        });      }    };    if (window.YT && window.YT.Player) {      onYouTubeIframeAPIReady();    } else {      window.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady;    }    return () => {      if (playerRef.current) {        playerRef.current.destroy(); // keep ?      }    };  }, [playerRef]);  return (<><iframe        ref={iframeRef}        width="884"        height="497"        src={link +'?enablejsapi=1&controls=0&disablekb=1&autoplay=0'}        title={title}        style={{ pointerEvents: 'none' }}        frameBorder="0"        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"        referrerPolicy="strict-origin-when-cross-origin"        allowFullScreen></iframe>      {!isPlaying && (<Button          type="button"          onClick={() => {            const didPlay = playVideo();            if (didPlay) setIsPlaying(true);          }}>          Play</Button>      )}</>  );};

The issue is that when I navigate away from this page (using Link from 'next/link') and come back to it, the iframe is destroyed. I understand I am destroying it in my useEffect cleanup, but do not understand why it is not re-instantiated when I navigate back to the page. Can someone explain why this happens?

When I comment out the playerRef.current.destroy() the iframe re-appears, but the fuctions associated with the YT player do not exist, i.e. "Uncaught TypeError: playerRef.current.playVideo is not a function". Any help would be appreciated


Viewing all articles
Browse latest Browse all 3723

Latest Images

Trending Articles



Latest Images