如何解决Next.js应用中ReferenceError: gapi is not defined报错问题
报错原因
报错1:Module not found: Can't resolve '@types/gapi'
@types/开头的npm包是TypeScript生态的类型声明包,仅包含TS类型定义代码,没有任何实际可运行的gapi业务逻辑,不能作为普通模块导入。这类包安装后TS会自动识别全局类型,不需要手动import。
报错2:ReferenceError: gapi is not defined
有两个核心原因:
- gapi本身是谷歌提供的浏览器端运行的SDK,不存在于Node.js运行环境中
- 你当前的代码写在Next.js的
pages/api/*路由下,这类路由是服务端接口,全程运行在Node.js环境,自然找不到全局的gapi变量
解决方法
首先明确使用场景:如果要使用gapi.auth2做前端身份验证,所有gapi相关逻辑必须放在前端客户端代码中,不能写在服务端API路由里。
步骤1:安装依赖
仅需要安装类型包作为开发依赖,不需要安装其他gapi相关npm包:
npm install --save-dev @types/gapi @types/gapi.auth2
步骤2:前端加载gapi SDK
在Next.js的pages/_document.tsx中添加script标签加载gapi官方SDK:
// pages/_document.tsx 核心片段 import Document, { Html, Head, Main, NextScript } from 'next/document' class MyDocument extends Document { render() { return ( <Html> <Head> <script src="https://apis.google.com/js/api.js" async defer /> </Head> <body> <Main /> <NextScript /> </body> </Html> ) } } export default MyDocument
步骤3:前端gapi.auth2身份验证示例
在任意前端页面组件中调用gapi,以下是Pages Router下的完整示例,如果使用App Router,在组件顶部添加'use client'指令后逻辑一致:
// pages/gapi-auth.tsx import { useEffect, useState } from 'react' export default function GapiAuthPage() { const [isGapiLoaded, setIsGapiLoaded] = useState(false) useEffect(() => { // 确保仅在客户端环境初始化gapi if (typeof window === 'undefined' || !window.gapi) return // 加载client和auth2模块 window.gapi.load('client:auth2', async () => { try { // 初始化gapi await window.gapi.client.init({ apiKey: '你的API密钥', clientId: '你的客户端ID', scope: 'https://www.googleapis.com/auth/webmasters', discoveryDocs: ['https://people.googleapis.com/$discovery/rest'] }) setIsGapiLoaded(true) console.log('gapi初始化完成') } catch (err) { console.error('gapi初始化失败', err) } }) }, []) // 登录方法 const handleLogin = async () => { if (!isGapiLoaded) return const authInstance = window.gapi.auth2.getAuthInstance() const user = await authInstance.signIn() console.log('登录用户信息', user.getBasicProfile()) // 可以获取access_token调用后续接口 console.log('访问令牌', user.getAuthResponse().access_token) } // 登出方法 const handleLogout = async () => { if (!isGapiLoaded) return const authInstance = window.gapi.auth2.getAuthInstance() await authInstance.signOut() console.log('已登出') } return ( <div> <button onClick={handleLogin} disabled={!isGapiLoaded}>谷歌账号登录</button> <button onClick={handleLogout} disabled={!isGapiLoaded}>登出</button> </div> ) }
服务端调用谷歌API替代方案
如果你确实需要在Next.js的服务端API路由中调用谷歌接口,不要使用gapi,改用谷歌官方的Node.js服务端SDKgoogleapis:
npm install googleapis
你原来的pages/api/test.ts可以改写为使用这个包完成接口调用,不需要依赖浏览器环境。
内容的提问来源于stack exchange,提问作者Ramin Bateni Parvar
相关产品推荐
相关产品推荐

