SSR / Next.js
warning
Never call new EvePlayer() at module scope. It touches document and
window internally, which do not exist during server-side rendering.
Use a dynamic import inside an effect, so construction runs only in the browser:
// components/VideoWrapper.tsx
'use client';
import { useEffect, useRef } from 'react';
export default function VideoWrapper() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
let player: import('@admmedia/eveplayer').EvePlayer;
void (async () => {
const { EvePlayer } = await import('@admmedia/eveplayer');
player = new EvePlayer(containerRef.current!, { widescreen: true });
player.setSource({ sources: [{ src: '/video.mp4', type: 'video/mp4' }] });
})();
return () => player?.dispose();
}, []);
return <div ref={containerRef} />;
}
Or defer the whole component with Next.js dynamic:
const VideoWrapper = dynamic(() => import('./VideoWrapper'), { ssr: false });
Until the player script runs, the container is an empty div, 0px tall. To
reserve the space and avoid a layout shift, give the placeholder (and the
container) the vjsp-widescreen class and create the player with
widescreen: true, so both are the same 16:9 box:
const VideoWrapper = dynamic(() => import('./VideoWrapper'), {
ssr: false,
loading: () => <div className="vjsp-widescreen" />,
});
See Player sizing for the other sizing options.
Remember to import the stylesheet once somewhere in the client bundle:
import '@admmedia/eveplayer/style.css';