plyr-react
plyr-react copied to clipboard
"ReferenceError: document is not defined" in Next.js13 & 14
I am using plyr-react in a Next.js 14.0.1 environment (also tried with v13) and pages using plyr-react (5.3.0) fail to load or build with errors of type "ReferenceError: document is not defined" node_modules\plyr\dist\plyr.js:302:21
From my understanding, it seems the runtime tries to access the document object where there isn't one, like when running in a server environment. These errors can be fixed by checking validity of the document object before accessing it, but I don't think this is a proper fix, it seems the code is being run within a context it shouldn't be run into.
Windows 10, Node.js 21.1.0, Next.js 14.0.1, plyr-react 5.3.0, react 18.2.0
FYI I didn't have this problem when I worked on my site about 6 months ago, but now I upgraded everything I have it all the time, this blocks the build.
Steps to reproduce:
- install latest next.js and example app using: npx create-next-app@latest
- npm install plyr-react
- into the app's src/app/page.tsx, import plyr and and a <Plyr> tag in the Home function.
import Plyr from "plyr-react"
import "plyr-react/plyr.css"
(...)
<Plyr (...) />
- npm run dev
- open page in browser and see the error "ReferenceError: document is not defined"
Same issue here. No idea what changed, please let me know if there's a package update that broke Plyr...
@maxiedaniels @eliyo @Clueed
I have created discussing on nextjs repo
https://github.com/vercel/next.js/discussions/58911
please add more question and details also there
@maxiedaniels @eliyo @Clueed I have created discussing on nextjs repo
please add more question and details also there
I don't know if this is an error due to nextjs version or your source code. But this error appears in nextjs 14.0.2 and above, but 14.0.1 still works normally.
The error disappeared for me, no idea why. I had already tried deleting node_modules and my package lock file, but it hadn’t fixed it. I gave up and then somehow a day later I realized the error had disappeared.
Also getting this error but with Remix
same, got this error with nextjs 14.0.2
same, got this error with nextjs 14.0.2 @chintan9 It only has errors with version 14.0.2 and above. Even the latest version 14.1.0 still has this error, however next.js seems to ignore it and allow buid.
@timomedia it allows me to run npm run dev if I recall but I can’t do an actual build or deploy on vercel
Hello, To fix it, make it client a component and use next dynamic import
const Plyr = dynamic(() => import("plyr-react"), { ssr: false });
it should work ;)
Hello, To fix it, make it client a component and use next dynamic import
const Plyr = dynamic(() => import("plyr-react"), { ssr: false });
it should work ;)
This works to render, but it doesn't seem possible to get the ref to to the component. If you just attach the ref
prop you get Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()
All my attempts beyond this to dynamically import usePlyr and do React.forwardRef() have failed, as well as all attempts to do a basic forwarded-ref component.
Currently stuck with not being able to use this library, which is a bummer.
I was getting this problem too but I now resolved it (I think). Here's an example component if it helps anyone out there:
"use client";
import { FC } from "react";
import dynamic from "next/dynamic";
import "plyr-react/plyr.css";
const Plyr = dynamic(async () => await import("plyr-react"), { ssr: false });
type Video = {
id: string;
source: Plyr.Provider;
};
type Props = {
video?: Video;
};
const VideoPlayer: FC<Props> = ({ video, ...rest }) => {
return video?.id && video?.source ? (
<Plyr
{...rest}
source={{
type: "video",
sources: [{ src: video.id, provider: video.source }],
}}
options={{
controls: [
"play",
"play-large",
"progress",
"current-time",
"mute",
"volume",
"fullscreen",
],
}}
/>
) : null;
};
export default VideoPlayer;
Interestingly, if I add className
onto the <Plyr />
component, it completely breaks it. Very odd. e.g. <Plyr className="this-will-break" />
. Perhaps usage of the hook might be better for these cases?
The dynamic load fixed it for me (const Plyr = dynamic(() => import("plyr-react"), { ssr: false });) edit I was getting a VERY weird bug that was breaking fast refresh and also an entire component, turns out it was this fix. So i had to do:
const PlyrComponent = React.useMemo(() => { return dynamic(() => import("plyr-react"), { ssr: false }); }, []);
And then <PlyrComponent ...> instead of <Plyr ...>
Just sharing in case someone else has the same bug!
@maxiedaniels @michaelpumo It really doesn't work. I tried using dynamic but it didn't work. I created a component called Player to use in different pages and using it the way you do doesn't work at all. Below is my original code that tried to use dynamic
"use client"
import React, { useEffect, useRef } from "react";
import dynamic from "next/dynamic";
import Hls from "hls.js";
const PlyrComponent = dynamic(() => import("plyr-react"), { ssr: false });
export default function Player({ videoUrl, poster }) {
const option = {
autoplay: false,
controls: [
'rewind',
'play',
'fast-forward',
'progress',
'current-time',
'duration',
'mute',
'volume',
'settings',
'quality',
'fullscreen',
],
};
const ref = useRef(null);
useEffect(() => {
const loadVideo = async () => {
if (ref.current && typeof window !== 'undefined') {
const plyr = ref.current.get('plyr');
if (plyr) {
var hls = new Hls();
hls.loadSource(videoUrl);
hls.attachMedia(plyr.media);
hls.on(Hls.Events.MANIFEST_PARSED, function () {
plyr.play();
});
}
}
};
loadVideo();
}, [videoUrl]);
return (
<PlyrComponent
ref={ref}
playsInline
source={{
type: "video",
sources: [{ src: videoUrl, type: 'application/vnd.apple.mpegurl' }],
}}
poster={poster}
options={option}
/>
);
}