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

Next.js13 Pages目录dynamic导入开发正常生产模式失效

Next.js 13 Pages 生产环境下Zoom Web SDK组件无法显示的问题排查与解决

问题描述

基于Next.js 13 Pages目录开发的应用,嵌入Zoom Web SDK实现会议功能,开发模式下运行正常,但构建生产版本后,访问/meeting页面时Zoom组件完全无法显示,组件似乎不存在。已尝试将ZoomCall组件的动态导入逻辑移至目录的index文件中导出,问题依旧。

相关代码片段

  • 原页面中的动态导入代码:
const ZoomCall = dynamic(() => import("@components/Zoom/ZoomCall"), {
  ssr: false,
  loading: () => "Loading...",
});
  • ZoomCall组件核心代码:
import { useEffect, useState } from "react";
import { ZoomMtg } from "@zoomus/websdk";
import ZoomMtgEmbedded from "@zoomus/websdk/embedded";
import useTranslation from "next-translate/useTranslation";

export default function ZoomCall({
  user,
  meetingNumber,
  setMeetingnumber,
  passWord,
  setMeetingPassword,
}) {
  const { t } = useTranslation();
  const [isComponentMounted, setIsComponentMounted] = useState(false);

  const signatureEndpoint = "/api/zoom/signature";
  const role = 0;

  useEffect(() => {
    ZoomMtg.setZoomJSLib("https://source.zoom.us/1.9.1/lib", "/av");
    ZoomMtg.preLoadWasm();
    ZoomMtg.prepareJssdk();
  }, []);

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

    fetch(signatureEndpoint, {
      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) {
    let meetingSDKElement = document.getElementById("meetingSDKElement");
    const client = ZoomMtgEmbedded.createClient();

    client.init({
      debug: true,
      zoomAppRoot: meetingSDKElement,
      language: "en-US",
      customize: {
        meetingInfo: [
          "topic",
          "host",
          "mn",
          "pwd",
          "telPwd",
          "invite",
          "participant",
          "dc",
          "enctype",
        ],
        toolbar: {
          buttons: [
            {
              text: "Custom Button",
              className: "CustomButton",
              onClick: () => {
                console.log("custom button");
              },
            },
          ],
        },
      },
    });

    client.join({
      sdkKey: process.env.NEXT_PUBLIC_ZOOM_API_KEY,
      signature: signature,
      meetingNumber: meetingNumber,
      password: passWord,
      userName: "..",
      userEmail: "ah....",
    });
  }

  return (
    <div>
      <div id="meetingSDKElement"></div>
      <button onClick={getSignature}>Join Meeting</button>
    </div>
  );
}
  • 目录index文件导出代码:
import dynamic from "next/dynamic";

export default dynamic(() => import("./ZoomCall"), { ssr: false });

可能的原因及解决方法

1. 修复Zoom SDK资源加载路径与版本

开发环境下资源加载不受严格限制,但生产环境中可能存在版本兼容性或CDN资源访问问题,建议升级到Zoom SDK最新稳定版,并修正资源加载路径:

// 修改ZoomCall组件中的useEffect
useEffect(() => {
  // 使用最新版SDK资源,避免旧版本兼容性问题
  ZoomMtg.setZoomJSLib("https://source.zoom.us/latest/lib", "/av");
  ZoomMtg.preLoadWasm();
  ZoomMtg.prepareJssdk();
}, []);

2. 优化动态导入配置

确保动态导入的路径绝对正确,同时添加更明确的加载状态配置,避免webpack chunk命名干扰:

// 页面中的动态导入修改为
const ZoomCall = dynamic(() => import("@components/Zoom/ZoomCall"), {
  ssr: false,
  loading: () => <div className="loading">加载中...</div>,
  suspense: false,
});

3. 改用React Ref获取DOM元素

生产环境中React渲染时机与开发环境有差异,直接通过document.getElementById可能获取不到元素,改用useRef确保元素引用可靠:

// 在ZoomCall组件中引入useRef
import { useEffect, useState, useRef } from "react";

export default function ZoomCall(...) {
  const meetingSDKRef = useRef(null);

  // ...

  function startMeeting(signature) {
    if (!meetingSDKRef.current) return;

    const client = ZoomMtgEmbedded.createClient();

    client.init({
      debug: true,
      zoomAppRoot: meetingSDKRef.current, // 使用ref引用DOM元素
      // 其他配置不变
    });

    // ...join逻辑不变
  }

  return (
    <div>
      <div ref={meetingSDKRef}></div> {/* 替换id为ref */}
      <button onClick={getSignature}>Join Meeting</button>
    </div>
  );
}

4. 验证生产环境环境变量

确认NEXT_PUBLIC_ZOOM_API_KEY在生产环境中已正确配置,Next.js生产构建时会将NEXT_PUBLIC_前缀的变量注入客户端代码,可通过查看构建后的静态文件确认变量是否存在,避免因变量缺失导致SDK初始化失败。

5. 检查生产环境API路由可用性

确保/api/zoom/signature接口在生产环境可正常访问,部分生产服务器可能会拦截API路由请求,需确认服务器配置未限制该路径的POST请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:05:53