Skip to content

Instantly share code, notes, and snippets.

@Lovor01
Created February 24, 2026 23:53
Show Gist options
  • Select an option

  • Save Lovor01/c7c0ffe55c3b87de712235c673683e61 to your computer and use it in GitHub Desktop.

Select an option

Save Lovor01/c7c0ffe55c3b87de712235c673683e61 to your computer and use it in GitHub Desktop.
Video.js React component
'use client';
import React from 'react';
import videojs from 'video.js';
import type Player from 'video.js/dist/types/player';
import 'video.js/dist/video-js.css';
interface VideoJSProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
options: any;
onReady?: (player: Player) => void;
className?: string;
}
export default function VideoJS ({ options, onReady, className }: VideoJSProps) {
const videoRef = React.useRef<HTMLDivElement>(null);
const playerRef = React.useRef<Player | null>(null);
React.useEffect(() => {
// Make sure Video.js player is only initialized once
if (!playerRef.current) {
// The Video.js player needs to be _inside_ the component el for React 18 Strict Mode.
const videoElement = document.createElement('video-js');
videoElement.classList.add('vjs-big-play-centered');
videoRef.current?.appendChild(videoElement);
const player = videojs(videoElement, options, () => {
videojs.log('player is ready');
if (onReady) {
onReady(player);
}
});
playerRef.current = player;
} else {
// Update existing player props
const player = playerRef.current;
player.autoplay(options.autoplay ?? false);
player.src(options.sources);
}
}, [options, onReady]);
// Dispose the Video.js player when the functional component unmounts
React.useEffect(() => {
const player = playerRef.current;
return () => {
if (player && !player.isDisposed()) {
player.dispose();
playerRef.current = null;
}
};
}, []);
return (
<div data-vjs-player className={className}>
<div ref={videoRef} />
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment