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

Next.js 14.1.0集成Leaflet自定义Hook时window未定义错误修复方案

修复Next.js 14.1.0中Leaflet集成的ReferenceError: window is not defined错误

问题原因

Leaflet是浏览器端专属库,核心逻辑依赖window对象,但Next.js默认开启服务端渲染(SSR),在服务端执行阶段不存在window,当你的自定义Hook在服务端初始化时调用Leaflet,就会触发该错误。

有效修复方案

1. 标记客户端组件(App Router)

在使用Leaflet Hook的组件或Hook文件顶部添加'use client'指令,强制该文件在客户端渲染:

'use client';

import { useLeafletMap } from './use-leaflet-map';

export default function MapPage() {
  useLeafletMap('map-container');
  return <div id="map-container" style={{ height: '400px' }} />;
}

同时确保use-leaflet-map.tsx和use-custom-map.tsx也添加该指令,避免服务端执行依赖window的代码。

2. 动态导入Leaflet及相关依赖

使用Next.js的next/dynamic动态导入地图组件,禁用SSR:

import dynamic from 'next/dynamic';

// 动态导入地图组件,服务端不渲染
const MapComponent = dynamic(() => import('../components/MapComponent'), {
  ssr: false,
  loading: () => <div>加载地图中...</div>
});

export default function Home() {
  return <MapComponent />;
}

在MapComponent内部再引入你的自定义Hook,确保Leaflet仅在客户端加载。

3. Hook内添加window存在性检查

在自定义Hook中,所有涉及Leaflet初始化的逻辑都包裹在typeof window !== 'undefined'判断中:

'use client';

import { useEffect } from 'react';
import L from 'leaflet';

export function useLeafletMap(mapId: string) {
  useEffect(() => {
    // 仅在客户端环境执行Leaflet初始化
    if (typeof window === 'undefined') return;

    const map = L.map(mapId).setView([51.505, -0.09], 13);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

    return () => map.remove();
  }, [mapId]);
}

4. 客户端动态加载Leaflet CSS

Leaflet的CSS也需确保在客户端加载,避免服务端渲染时样式报错:

'use client';

import { useEffect } from 'react';

export function useLeafletStyles() {
  useEffect(() => {
    import('leaflet/dist/leaflet.css');
  }, []);
}

在地图组件中调用该Hook即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:00:08