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

Next.js使用PrimeReact GMap集成Google Maps报google未定义如何解决

错误根因

ReferenceError: google is not defined 报错由两个核心问题共同导致:

  • PrimeReact GMap 组件强依赖浏览器全局google对象,该对象仅在Google Maps JavaScript SDK加载完成后才会注入,官方示例默认省略了SDK加载的前置步骤
  • Next.js 默认开启服务端渲染,服务端执行环境无浏览器全局API,且GMap为纯客户端组件,直接静态导入并在服务端执行渲染逻辑会直接触发引用错误
修复步骤

1. 配置客户端渲染

禁止GMap组件在服务端运行,根据你使用的Next.js路由模式做对应配置:

  • App Router 项目:在组件文件顶部添加'use client'指令
  • Pages Router / App Router 通用:使用Next.js内置的dynamic方法动态导入GMap组件,关闭SSR:
import dynamic from 'next/dynamic';
// 动态导入GMap,关闭服务端渲染,配置加载占位
const GMap = dynamic(
  () => import('primereact/gmap').then(module => module.GMap),
  { 
    ssr: false,
    loading: () => <div style={{minHeight: '320px'}}>地图加载中...</div>
  }
);

2. 预加载Google Maps SDK

在客户端侧手动加载SDK,等待SDK加载完成、全局google对象注入后再渲染GMap组件,可通过自定义Hook实现加载逻辑:

import { useState, useEffect } from 'react';

const useGoogleMapsLoader = (apiKey) => {
  const [isLoaded, setIsLoaded] = useState(false);

  useEffect(() => {
    // 已加载过直接返回
    if (window.google?.maps) {
      setIsLoaded(true);
      return;
    }
    // 创建脚本标签注入SDK
    const script = document.createElement('script');
    script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}`;
    script.async = true;
    script.defer = true;
    script.onload = () => setIsLoaded(true);
    document.body.appendChild(script);

    return () => {
      // 组件卸载时移除脚本,避免重复注入
      if (document.body.contains(script)) {
        document.body.removeChild(script);
      }
    }
  }, [apiKey]);

  return isLoaded;
}

注意:需要提前申请Google Maps服务的API密钥,同时在对应云服务控制台开通Maps JavaScript API权限、配置生产域名白名单,避免密钥被滥用。

3. 增加渲染判断逻辑

在组件中结合SDK加载状态控制GMap的渲染时机,完整可用代码如下:

'use client'; // App Router 项目保留此行,Pages Router可删除
import { useState, useEffect } from 'react';
import dynamic from 'next/dynamic';

const GMap = dynamic(
  () => import('primereact/gmap').then(module => module.GMap),
  { 
    ssr: false,
    loading: () => <div style={{width: '100%', minHeight: '320px'}}>地图加载中...</div>
  }
);

const useGoogleMapsLoader = (apiKey) => {
  const [isLoaded, setIsLoaded] = useState(false);

  useEffect(() => {
    if (window.google?.maps) {
      setIsLoaded(true);
      return;
    }
    const script = document.createElement('script');
    script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}`;
    script.async = true;
    script.defer = true;
    script.onload = () => setIsLoaded(true);
    document.body.appendChild(script);

    return () => {
      if (document.body.contains(script)) {
        document.body.removeChild(script);
      }
    }
  }, [apiKey]);

  return isLoaded;
}

const DealershipLocation = () => {
  // 替换为你自己的Google Maps API密钥
  const isMapLoaded = useGoogleMapsLoader('YOUR_GOOGLE_MAPS_API_KEY');
  const options = {
    center: {lat: 36.890257, lng: 30.707417},
    zoom: 12
  };

  return (
    <div>
      {isMapLoaded ? (
        <GMap options={options} style={{width: '100%', minHeight: '320px'}} />
      ) : (
        <div style={{width: '100%', minHeight: '320px'}}>地图资源加载中...</div>
      )}
    </div>
  )
}

export default DealershipLocation
常见排查点
  • 如果SDK加载后仍然报错,检查API密钥是否有效、是否开通了对应API权限,浏览器控制台是否有SDK加载相关的403/401错误
  • 如果页面存在多实例GMap的场景,调整脚本加载逻辑,避免重复注入SDK脚本
  • PrimeReact版本需和React、Next.js版本匹配,版本不兼容也可能导致组件渲染异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:06:22