Search code examples
javascriptreactjsnext.jszoom-sdk

Cannot import module in nextjs


I tried to import zoom websdk module to next js but it failed because window object is not defined.

What i did is just trying to import websdk module but this error happened

enter image description here

I'm using nextjs v12 with create-next-app and my code is pretty simple. here's on my pages/index.js

import { ZoomMtg } from '@zoomus/websdk';

const Page = () => {

    const handleClick = async () => {

    }

    return (
        <main>
            {/* get meeting number and role here (and password maybe) */}
            <button onClick={handleClick}>Join meeting</button>
            {/* <div>{meetingUrl && <ZoomWindow url={meetingUrl} />}</div>  */}
        </main>
    )
}

export default Page

is the websdk package broken or something?


Solution

  • Keep in mind that NextJS runs both in the browser and on the server. During a server side render, window is not defined. You can use dynamic imports to only import some dependencies on the browser, where window will be defined.

    https://nextjs.org/docs/advanced-features/dynamic-import

    Here is the example from NextJS

    import dynamic from 'next/dynamic'
    
    const DynamicComponentWithNoSSR = dynamic(
      () => import('../components/hello3'),
      { ssr: false }
    )
    
    function Home() {
      return (
        <div>
          <Header />
          <DynamicComponentWithNoSSR />
          <p>HOME PAGE is here!</p>
        </div>
      )
    }
    
    export default Home
    

    You can do essentially the same, but with your dependency.

    Edit: I thought ZoomMtg was a component. The first example from the docs is closer to what you need for ZoomMtg.

    Something like this should do the trick:

      const [zoomMtg, setZoomMtg] = useState(null)
      useEffect(() => {
       ( async () => {
         if(typeof window !== "undefined"){
          const {ZoomMtg} = (await import('@zoomus/websdk'))
          setZoomMtg(ZoomMtg)
        }
        })()
      }, [])
    

    Then just confirm zoomMtg the state variable is defined before rendering your component. {!!zoomMtg && <YourComponent />

    NOTE: If you have control over the YourComponent module, then a better alternative would be to move the import of ZoomMtg to this file and just import it normally. Then import YourComponent with the nextjs dynamic syntax.