Next.js13+App Router中mapbox-gl报TypeError: createElement undefined如何解决?
解决Next.js中mapbox-gl构建报错:Cannot read property 'createElement' of undefined
问题背景
在Next.js应用中使用mapbox-gl@^2.15.0,地图可正常渲染,但终端出现运行时错误导致构建失败,错误指向mapbox-gl内部的resolveURL方法。
报错信息
- error node_modules\mapbox-gl\dist\mapbox-gl.js (31:21756) @ Object.resolveURL - error TypeError: Cannot read property 'createElement' of undefined
问题原因
mapbox-gl的setRTLTextPlugin方法会调用浏览器环境的document.createElement,而Next.js在服务端渲染阶段没有document对象。当前代码中该方法直接写在组件外部,会在服务端执行,因此触发报错。
解决方案
将依赖浏览器环境的mapbox-gl操作(如setRTLTextPlugin)移到useEffect钩子内部,确保仅在客户端执行;同时可通过typeof window !== 'undefined'做额外的环境判断,避免服务端执行相关代码。
修改后的组件代码
"use client"; import React, { useRef, useEffect, useState } from "react"; import mapboxgl from "mapbox-gl"; import MapboxLanguage from '@mapbox/mapbox-gl-language'; const Map = () => { const mapContainer = useRef(null); const map = useRef(null); const [lng, setLng] = useState(35.90719); const [lat, setLat] = useState(31.97182); const [zoom, setZoom] = useState(11.5); const [mapIsLoaded, setMapIsLoaded] = useState(false); useEffect(() => { if (map.current) return; // 仅初始化一次地图 // 仅在客户端环境设置RTL文本插件 if (typeof window !== 'undefined') { mapboxgl.setRTLTextPlugin('https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.3/mapbox-gl-rtl-text.js'); } // 初始化地图 map.current = new mapboxgl.Map({ container: mapContainer.current, style: "mapbox://styles/mapbox/streets-v11", center: [lng, lat], zoom: zoom, hash: true, }); map.current.on("load", () => { setMapIsLoaded(true); }); // 组件卸载时清理地图实例 return () => map.current.remove(); }, []); return ( <div ref={mapContainer} style={{ minHeight: "100vh", minWidth: "100vw" }} /> ); }; export default Map;
额外优化(可选)
如果仍存在服务端打包问题,可使用Next.js的动态导入方式禁用该组件的服务端渲染:
// 在引入Map组件的文件中 import dynamic from 'next/dynamic'; const Map = dynamic(() => import('./components/Map'), { ssr: false });
内容的提问来源于stack exchange,提问作者Ibra
相关产品推荐
相关产品推荐

