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

Next.js集成Firebase AppCheck reCaptcha构建报错:document未定义

解决Next.js中Firebase AppCheck reCaptcha构建报错"document is not defined"

问题原因

Next.js的服务端渲染(SSR)环境中不存在浏览器的document对象,而ReCaptchaV3Provider初始化时会调用依赖document的DOM操作代码,导致yarn build时抛出ReferenceError: document is not defined错误。

解决方案

方案一:仅在客户端环境初始化AppCheck

将AppCheck的初始化逻辑包裹在typeof window !== 'undefined'判断中,确保代码只在浏览器环境执行:

修改后的Firebase配置代码:

/* eslint no-undef: 0 */
import {
  initializeAppCheck,
  ReCaptchaV3Provider,
  getToken,
} from 'firebase/app-check';


if (firebaseConfig?.projectId) {
  const app = initializeApp(firebaseConfig);

  auth = getAuth(app);
  firestore = getFirestore(app);
  firebase = app;

  storage = getStorage();
  googleProvider = new GoogleAuthProvider();

  if (app.name && typeof window !== 'undefined') {
    analytics = getAnalytics(app);
  }

  // Pass your reCAPTCHA v3 site key (public key) to activate(). Make sure this
  // key is the counterpart to the secret key you set in the Firebase console.
  if (IS_PRODUCTION && RECAPTCHA_SITE_KEY && typeof window !== 'undefined') {
    const appCheck = initializeAppCheck(app, {
      provider: new ReCaptchaV3Provider(RECAPTCHA_SITE_KEY as string),
      isTokenAutoRefreshEnabled: true,
    });

    getToken(appCheck)
      .then(() => {
        console.log('success');
      })
      .catch(error => {
        console.log(error.message);
      });
  }
}

方案二:动态导入AppCheck初始化模块

使用Next.js的dynamic导入功能,将AppCheck的初始化代码封装成独立模块并禁用SSR:

  1. 创建独立的AppCheck初始化文件(比如app-check-initializer.js):
import { initializeAppCheck, ReCaptchaV3Provider, getToken } from 'firebase/app-check';
import { getApp } from 'firebase/app';

export default function InitializeAppCheck() {
  const app = getApp();
  if (process.env.NODE_ENV === 'production' && process.env.RECAPTCHA_SITE_KEY) {
    const appCheck = initializeAppCheck(app, {
      provider: new ReCaptchaV3Provider(process.env.RECAPTCHA_SITE_KEY),
      isTokenAutoRefreshEnabled: true,
    });

    getToken(appCheck)
      .then(() => console.log('success'))
      .catch(error => console.log(error.message));
  }
  return null; // 组件无需渲染内容
}
  1. 在_app.js中动态导入该组件:
import dynamic from 'next/dynamic';

const InitializeAppCheck = dynamic(() => import('./app-check-initializer'), {
  ssr: false
});

function MyApp({ Component, pageProps }) {
  return (
    <>
      <InitializeAppCheck />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

关键说明

Next.js构建阶段会执行服务端渲染流程,此时无法访问浏览器专属的API(如document、window)。通过上述两种方式,可确保依赖浏览器环境的AppCheck初始化代码仅在客户端运行,避免构建报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:07:50