You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js集成Zoom SDK报错:ReferenceError: self is not defined

解决Next.js集成Zoom SDK时的ReferenceError: self is not defined错误

这个错误的核心原因是Next.js的服务端渲染(SSR)机制:Zoom Meeting SDK依赖浏览器环境的self全局对象,但服务器端渲染时不存在这个对象,所以会抛出该错误。

下面是两种可行的解决方案:

方案1:动态导入Zoom SDK并禁用SSR

利用Next.js的next/dynamic让Zoom SDK仅在客户端加载,避免服务器端执行相关代码:

import dynamic from 'next/dynamic';
import { useEffect } from 'react';

// 动态导入ZoomMtg,禁用服务端渲染
const ZoomMtg = dynamic(() => import('@zoomus/websdk').then(mod => mod.ZoomMtg), {
  ssr: false
});

function App() {
  // 仅在客户端完成渲染后初始化Zoom SDK
  useEffect(() => {
    if (ZoomMtg) {
      ZoomMtg.setZoomJSLib('https://source.zoom.us/2.14.0/lib', '/av');
      ZoomMtg.preLoadWasm();
      ZoomMtg.prepareWebSDK();
    }
  }, []);

  const authEndpoint = '';
  const sdkKey = '';
  const meetingNumber = '123456789';
  const passWord = '';
  const role = 0;
  const userName = 'React';
  const userEmail = '';
  const registrantToken = '';
  const zakToken = '';
  const leaveUrl = 'http://localhost:3000';

  function getSignature(e) {
    e.preventDefault();

    fetch(authEndpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        meetingNumber: meetingNumber,
        role: role,
      }),
    })
      .then((res) => res.json())
      .then((response) => {
        startMeeting(response.signature);
      })
      .catch((error) => {
        console.error(error);
      });
  }

  function startMeeting(signature) {
    const zmmtgRoot = document.getElementById('zmmtg-root');
    if (zmmtgRoot) {
      zmmtgRoot.style.display = 'block';
    }

    if (ZoomMtg) {
      ZoomMtg.init({
        leaveUrl: leaveUrl,
        success: (success) => {
          console.log(success);

          ZoomMtg.join({
            signature: signature,
            sdkKey: sdkKey,
            meetingNumber: meetingNumber,
            passWord: passWord,
            userName: userName,
            userEmail: userEmail,
            tk: registrantToken,
            zak: zakToken,
            success: (success) => {
              console.log(success);
            },
            error: (error) => {
              console.log(error);
            },
          });
        },
        error: (error) => {
          console.log(error);
        },
      });
    }
  }

  return (
    <main>
      <h1>Zoom Meeting SDK Sample React</h1>
      <button onClick={getSignature}>Join Meeting</button>
    </main>
  );
}

export default App;

方案2:判断浏览器环境后初始化

如果不想用动态导入,可以通过检查window对象是否存在,确保仅在浏览器环境执行Zoom的初始化代码:

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

function App() {
  useEffect(() => {
    // 仅在浏览器环境中执行初始化逻辑
    if (typeof window !== 'undefined') {
      ZoomMtg.setZoomJSLib('https://source.zoom.us/2.14.0/lib', '/av');
      ZoomMtg.preLoadWasm();
      ZoomMtg.prepareWebSDK();
    }
  }, []);

  // 其余变量、方法和返回部分与原代码一致,可参考方案1中的对应内容
}

export default App;

关键改动说明

  • 动态导入+禁用SSR:确保Zoom SDK完全在客户端加载,绕开服务器端的环境限制。
  • useEffect包裹初始化:useEffect的回调只会在客户端渲染完成后触发,此时self等浏览器全局对象已存在。
  • 添加存在性检查:在使用ZoomMtg和DOM元素时增加判断,避免客户端加载延迟导致的调用失败问题。

内容的提问来源于stack exchange,提问作者Kyrylo Usichenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:50:25