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:
- 创建独立的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; // 组件无需渲染内容 }
- 在
_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
相关产品推荐
相关产品推荐

