Next.js 12导入Zoom WebSDK提示window对象未定义问题咨询
Next.js 12导入Zoom WebSDK报window未定义的解决方案
问题原因
该报错既不是@zoomus/websdk包本身的问题,也不是业务代码逻辑错误,核心是Next.js默认的*服务端渲染(SSR)*机制导致:
@zoomus/websdk包在导入阶段就会直接调用浏览器端的window对象- Next.js pages路由默认会在服务端先执行一次组件代码做预渲染,服务端环境不存在
window对象,因此只要在顶层导入SDK就会触发报错
报错截图:
触发报错的原始代码:
import { ZoomMtg } from '@zoomus/websdk'; const Page = () => { const handleClick = async () => { } return ( <main> {/* 此处获取会议号、用户角色,可能还需要会议密码 */} <button onClick={handleClick}>加入会议</button> {/* <div>{meetingUrl && <ZoomWindow url={meetingUrl} />}</div> */} </main> ) } export default Page
解决方案
提供两种生产环境常用的修复方式:
方案1:封装Zoom组件,通过动态导入关闭SSR
- 新建独立组件
components/ZoomJoinButton.js,把Zoom SDK的导入和相关逻辑都放在该组件内:
import { ZoomMtg } from '@zoomus/websdk'; const ZoomJoinButton = ({ meetingId, role, password }) => { const handleJoinMeeting = async () => { // 此处写原有加入会议的业务逻辑 } return <button onClick={handleJoinMeeting}>加入会议</button> } export default ZoomJoinButton;
- 在
pages/index.js中使用next/dynamic动态导入该组件,明确禁用服务端渲染:
import dynamic from 'next/dynamic'; const ZoomJoinButton = dynamic(() => import('../components/ZoomJoinButton'), { ssr: false, // 可选配置:组件加载过程中显示的占位内容 loading: () => <button disabled>加载中...</button> }); const Page = () => { return ( <main> {/* 此处获取会议号、用户角色、会议密码等参数传入组件 */} <ZoomJoinButton /> {/* 其余页面逻辑 */} </main> ) } export default Page
方案2:在useEffect中动态导入SDK
如果不想拆分组件,可以直接在仅客户端执行的useEffect钩子中完成SDK导入:
import { useState, useEffect } from 'react'; const Page = () => { const [ZoomMtg, setZoomMtg] = useState(null); useEffect(() => { // 仅在浏览器端加载SDK const initZoomSdk = async () => { const sdkModule = await import('@zoomus/websdk'); setZoomMtg(sdkModule.ZoomMtg); } initZoomSdk(); }, []); const handleClick = async () => { // 确保SDK加载完成后再执行业务逻辑 if (!ZoomMtg) return; // 此处写原有加入会议的业务逻辑 } return ( <main> <button onClick={handleClick}>加入会议</button> </main> ) } export default Page
内容的提问来源于stack exchange,提问作者Roby Cigar
相关产品推荐
相关产品推荐

