SSR error `window is not defined`
Environment
Next.js
- Dash.js version: 5.0.0
Steps to reproduce
- Add
import * as DASH from 'dashjs'in a Next.js project.
Observed behavior
Throws error.
Console output
⨯ ReferenceError: window is not defined
at (ssr)/./node_modules/dashjs/dist/modern/esm/dash.all.min.js (.next/server/vendor-chunks/dashjs.js:20:1)
at __webpack_require__ (.next/server/webpack-runtime.js:33:43)
Expected behavior
Not failing.
I don't quite understand the use case here, can you please provide more details. Do you want to use dash.js on the server side?
For playback, dash.js requires the Media Source Extensions and the Encrypted Media Extensions. If the window object is not defined, then the APIs are not available and dash.js can not be used.
As you may know, during SSR client-side components are also run on the server. In my case in my Player component. Typicaly these cases are solved by having an if (typeof window !== "undefined") check in libraries.
Hi @wintercounter,
AFAIK, even for the client components (with "use client" directive), Next.js tries to load the modules on the server side. I have tried dynamic/lazy import as suggested here: https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading. no luck. Then, I fixed the issue as follows;
export const DashPlayer: React.FC<Props> = (props: Props) => {
const { src } = props;
const videoRef = useRef<HTMLVideoElement>(null);
const [dashLibrary, setDashLibrary] = useState<any>(null);
useEffect(() => {
const loadModule = async () => {
try {
setDashLibrary(await import('dashjs'));
} catch (error) {
console.error('Failed to load dashjs:', error);
}
};
loadModule()
.then(() => console.debug('dashjs library loaded'))
.catch(() => console.error('Failed to load dashjs library'));
}, []);
useEffect(() => {
if (!videoRef.current || !dashLibrary) return;
const player = dashLibrary.MediaPlayer().create();
player.initialize(videoRef.current, src, true);
return () => {
if (player) player.reset();
console.debug('dashjs player destroyed');
};
}, [dashLibrary, src]);
return <video ref={videoRef} />
}
please note that this is the simplified version and might be missing some points on the copy paste, but overall this is the idea.
I hope this helps.
Yes, with dynamic it works. But I don't want that, I want to bundle Dash using normal import for faster initial playback.
On Tue, 1 Apr 2025, 14:53 Burak Kara, @.***> wrote:
Hi @wintercounter https://github.com/wintercounter,
AFAIK, even for the client components (with "use client" directive), Next.js tries to load the modules on the server side. I have tried dynamic/lazy import as suggested here: https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading. no luck. Then, I fixed the issue as follows;
export const DashPlayer: React.FC<Props> = (props: Props) => { const { src } = props;
const videoRef = useRef<HTMLVideoElement>(null); const [dashLibrary, setDashLibrary] = useState<any>(null); useEffect(() => { const loadModule = async () => { try { setDashLibrary(await import('dashjs')); } catch (error) { console.error('Failed to load dashjs:', error); } }; loadModule() .then(() => console.debug('dashjs library loaded')) .catch(() => console.error('Failed to load dashjs library')); }, []); useEffect(() => { if (!videoRef.current || !dashLibrary) return; const player = dashLibrary.MediaPlayer().create(); player.initialize(videoRef.current, src, true); return () => { if (player) player.reset(); console.debug('dashjs player destroyed'); }; }, [dashLibrary, src]); return <video ref={videoRef} />}
please note that this is the simplified version and I might be missing some points on the copy paste, but overall this is the idea. I hope this helps.
— Reply to this email directly, view it on GitHub https://github.com/Dash-Industry-Forum/dash.js/issues/4728#issuecomment-2769263541, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHLJQAJSNLF446CKTUDCJD2XKD6FAVCNFSM6AAAAABZTNZJA2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONRZGI3DGNJUGE . You are receiving this because you were mentioned.Message ID: @.***> [image: burak-kara]burak-kara left a comment (Dash-Industry-Forum/dash.js#4728) https://github.com/Dash-Industry-Forum/dash.js/issues/4728#issuecomment-2769263541
Hi @wintercounter https://github.com/wintercounter,
AFAIK, even for the client components (with "use client" directive), Next.js tries to load the modules on the server side. I have tried dynamic/lazy import as suggested here: https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading. no luck. Then, I fixed the issue as follows;
export const DashPlayer: React.FC<Props> = (props: Props) => { const { src } = props;
const videoRef = useRef<HTMLVideoElement>(null); const [dashLibrary, setDashLibrary] = useState<any>(null); useEffect(() => { const loadModule = async () => { try { setDashLibrary(await import('dashjs')); } catch (error) { console.error('Failed to load dashjs:', error); } }; loadModule() .then(() => console.debug('dashjs library loaded')) .catch(() => console.error('Failed to load dashjs library')); }, []); useEffect(() => { if (!videoRef.current || !dashLibrary) return; const player = dashLibrary.MediaPlayer().create(); player.initialize(videoRef.current, src, true); return () => { if (player) player.reset(); console.debug('dashjs player destroyed'); }; }, [dashLibrary, src]); return <video ref={videoRef} />}
please note that this is the simplified version and I might be missing some points on the copy paste, but overall this is the idea. I hope this helps.
— Reply to this email directly, view it on GitHub https://github.com/Dash-Industry-Forum/dash.js/issues/4728#issuecomment-2769263541, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHLJQAJSNLF446CKTUDCJD2XKD6FAVCNFSM6AAAAABZTNZJA2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONRZGI3DGNJUGE . You are receiving this because you were mentioned.Message ID: @.***>