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

Next.js引入Agora SDK后刷新页面触发“ReferenceError: window is not defined”错误的解决求助

解决Next.js中Agora SDK的"ReferenceError: window is not defined"错误

我明白你卡在这里有多难受!这个问题的根源很明确:Agora RTC SDK依赖浏览器环境的window对象,但Next.js在服务器端渲染(SSR)阶段并没有这个对象,所以当页面刷新时,服务器端执行到Agora的初始化代码就会报错。你尝试用next/dynamic是对的,但可能是使用方式不对——因为createClient和createMicrophoneAudioTrack是需要执行的函数,直接动态导入整个模块的话,服务器端还是会尝试执行这些代码。

下面给你两种可行的解决方案,根据你的Next.js版本选择:


方案一:用客户端组件隔离Agora逻辑(Next.js 13+ App Router)

如果你的项目用的是App Router,最简单的方式是用'use client'指令把Agora相关的代码限定在客户端执行:

  1. 创建一个客户端专属的Agora配置文件(比如agora-providers.jsx):
'use client';

import { createClient, createMicrophoneAudioTrack } from "agora-rtc-react";

const appId = "***";
const token = null;
const config = { mode: "rtc", codec: "vp8", appId: appId, token: token };

export const useClient = createClient(config);
export const useMicrophoneAudioTrack = createMicrophoneAudioTrack();
export const channelName = "Main";
  1. 在你的room.jsx中导入并使用:
'use client';
import { useClient, useMicrophoneAudioTrack, channelName } from './agora-providers';

export default function Room() {
  const client = useClient();
  const { ready, track } = useMicrophoneAudioTrack();

  // 你的页面逻辑和渲染代码
  return (
    <div>
      {/* 渲染内容 */}
    </div>
  );
}

'use client'会告诉Next.js这个组件只能在客户端执行,服务器端不会渲染它,自然就不会触发window相关的错误。


方案二:用next/dynamic禁用SSR(适用于所有Next.js版本)

如果是Pages Router,或者你更习惯用动态导入,可以把使用Agora hooks的逻辑放到单独组件里,再动态导入这个组件并禁用SSR:

  1. 创建AgoraRoomContent.jsx组件:
import { useClient, useMicrophoneAudioTrack, channelName } from './settings';

export default function AgoraRoomContent() {
  const client = useClient();
  const { ready, track } = useMicrophoneAudioTrack();

  // 你的组件逻辑
  return (
    <div>
      {/* 渲染内容 */}
    </div>
  );
}
  1. 修改settings.js,确保初始化只在客户端执行:
import { createClient, createMicrophoneAudioTrack } from "agora-rtc-react";

const appId = "***";
const token = null;
const config = { mode: "rtc", codec: "vp8", appId: appId, token: token };

// 只在客户端环境下初始化Agora hooks
let useClient;
let useMicrophoneAudioTrack;
export const channelName = "Main";

if (typeof window !== 'undefined') {
  useClient = createClient(config);
  useMicrophoneAudioTrack = createMicrophoneAudioTrack();
}

export { useClient, useMicrophoneAudioTrack };
  1. 在room.jsx中动态导入组件:
import dynamic from 'next/dynamic';

// 动态导入组件,禁用SSR
const AgoraRoomContent = dynamic(() => import('./AgoraRoomContent'), {
  ssr: false,
  loading: () => <div>Loading Agora components...</div>
});

export default function Room() {
  return <AgoraRoomContent />;
}

为什么之前的next/dynamic会报错?

你之前直接动态导入settings.js的问题在于:即使动态导入,settings.js里的代码还是会在服务器端被执行,createClient和createMicrophoneAudioTrack会尝试访问window导致错误。上面的方案要么把初始化逻辑放到客户端组件里,要么用typeof window !== 'undefined'判断,确保这些代码只在浏览器里运行。

这样修改后,不管是首次进入还是刷新页面,都不会再出现window is not defined的错误了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:59:05