Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video.js in App Route - window is not defined #61740

Closed
mufteev opened this issue Feb 6, 2024 · 14 comments · Fixed by #62051
Closed

Video.js in App Route - window is not defined #61740

mufteev opened this issue Feb 6, 2024 · 14 comments · Fixed by #62051
Labels
bug Issue was opened via the bug report template. locked

Comments

@mufteev
Copy link

mufteev commented Feb 6, 2024

Link to the code that reproduces this issue

https://codesandbox.io/p/github/mufteev/nextjs-videojs-app-bug/main

To Reproduce

  1. pnpm build
  2. pnpm start

Current vs. Expected behavior

Current
Catch Uncaught Error: Uncaught ReferenceError: window is not defined in console and not work video.js
Cloned an example from a folder https://github.com/vercel/next.js/tree/canary/examples/with-videojs and ported to App Router
I get an error when using App Router in 14.1.0 (latest), but if I change the version to ^13.5.6 - Video.js worked.

Expected
Video.js libraries initialized and mount component similar like previous major version

It is worth noting that everything works fine in dev mode, and the bug itself occurs in production

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #15-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan  9 17:03:36 UTC 2024
Binaries:
  Node: 21.6.1
  npm: 10.2.4
  Yarn: N/A
  pnpm: 8.15.1
Relevant Packages:
  next: 14.1.0
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router

Which stage(s) are affected? (Select all that apply)

next start (local)

Additional context

I tested my reproduction in 14.1.1-canary.38 and and I still got the error:

blob:https://ly5p9t-3000.csb.app/b8589df3-9974-4a07-9038-ff100f3439fd:545 Uncaught ReferenceError: window is not defined
blob:https://ly5p9t-3000.csb.app/e2588c9a-dda0-447c-bc9c-69f532a83de7:6147 Uncaught ReferenceError: window is not defined
blob:https://ly5p9t-3000.csb.app/2f11b57f-873e-410d-b799-d7e1b46807a6:6147 Uncaught ReferenceError: window is not defined

Link github reproduction: nextjs-videojs-app-bug

@mufteev mufteev added the bug Issue was opened via the bug report template. label Feb 6, 2024
@hc0503
Copy link

hc0503 commented Feb 7, 2024

Hi @mufteev , you should import the component as dynamic with ssr: false.

const Player = dynamic(() => import("../components/Player"), {ssr: false})

The Player component should be export default.

@mufteev
Copy link
Author

mufteev commented Feb 7, 2024

Hi @hc0503, i update reproduction https://codesandbox.io/p/github/mufteev/nextjs-videojs-app-bug/main

import dynamic from "next/dynamic";
const Player = dynamic(() => import("../components/Player"), {
  ssr: false,
});

But... it didn't help

@hc0503
Copy link

hc0503 commented Feb 7, 2024

Hi @hc0503, i update reproduction https://codesandbox.io/p/github/mufteev/nextjs-videojs-app-bug/main

import dynamic from "next/dynamic";
const Player = dynamic(() => import("../components/Player"), {
  ssr: false,
});

But... it didn't help

@mufteev , Did you export Player component as default? windows undefined error doesn't occurs in my end.

@mufteev
Copy link
Author

mufteev commented Feb 7, 2024

component as default

@hc0503

Yep, sorry i made changes to the repository, but did not apply it. You now see changes with dynamic import in https://codesandbox.io/p/github/mufteev/nextjs-videojs-app-bug/main

Import without SSR not help.

This bug is similar to #60920 or #60644

@Laityned
Copy link
Contributor

Laityned commented Feb 7, 2024

Nextjs app directory has strict mode by default enabled. Therefore, the videojs player is not loading properly.
The videojs docs for react are updated to tackle the problem in strictmode, check those out:

PR
Docs

Following their guide, you will also not have a window is not defined error in production

@mufteev
Copy link
Author

mufteev commented Feb 7, 2024

No, I still think it's not about React 18 (strictMode as say @Laityned) or the import method (dynamic + !SSR @hc0503 )

Because I've downgraded the version to Next@14.0.0 and reproduction start worked!

Test version:

  • 14.0.0 - worked
  • 14.0.5-canary.19 - worked
  • 14.1.0 - NOT worked

P.S. this bug is definitely not related to React 18, because at the very beginning I specified version 13.5.6 - it also used React 18 (this can be seen from the commits in the reproduction)

@Laityned
Copy link
Contributor

Laityned commented Feb 7, 2024

You are indeed right!

However, following the other approach to load videojs, you can get it working in 14.1.0:
Working example

@Laityned
Copy link
Contributor

Laityned commented Feb 7, 2024

I tried to narrow it down to a particular version:

14.0.5-canary.19 is still working
14.0.5-canary.20 is not working

@KJ-Chiu
Copy link

KJ-Chiu commented Feb 7, 2024

For me, using mp4 works but throw ReferenceError: window is not defined when using application/x-mpegURL

video.js@8.10.0
next@14.1.0

  const videoJsOptions = {
    controls: false,
    responsive: true,
    full: true,
    liveui: isLive,
    sources: [{ src, type: isLive ? "application/x-mpegURL" : "video/mp4" }],
  };

@KJ-Chiu
Copy link

KJ-Chiu commented Feb 7, 2024

downgrade next to 14.0.5-canary.19 works for me

@kmvan
Copy link

kmvan commented Feb 8, 2024

image

I got Uncaught Error: Element type is invalid. Received a promise that resolves to: undefined. Lazy element type must resolve to a class or function. at mountLazyComponent (webpack-internal:///(/app-pages-browser)/./node_modules/.pnpm/next@14.1.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:14585:19)

@JesseSinivuori
Copy link

JesseSinivuori commented Feb 10, 2024

The window object is not available in server components. The Player components is a client component, but idk why sometimes even that doesn't help. You can do this client check trick in Player component and just return null if isClient is not true.

@mulfyx
Copy link

mulfyx commented Feb 12, 2024

const Player = dynamic(
   () => import("../components/Player").then((mod) => ({ default: mod.Player }),
   { ssr: false },
);

@huozhi huozhi closed this as completed in cfedc52 Feb 14, 2024
huozhi added a commit that referenced this issue Feb 28, 2024
)

Disable swc transform optimizer for node_modules in browser layer of app
router bundles

Fixes #61858
Fixes #60644
Fixes #60920
Fixes #61740
Closes NEXT-2418

In browser there could be not only one runtime, it could have both js
worker and browser. In js worker the `typeof window` is not as same as
in browser, so disabling the swc optimizer which will replace the code.
Leave the condition as it as.
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 29, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. locked
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants
@kmvan @Laityned @mulfyx @KJ-Chiu @hc0503 @mufteev @JesseSinivuori and others