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

NextJS集成第三方库仍触发window is not defined错误求助

解决NextJS集成@shopify/draggable时服务端window is not defined错误

问题根源

@shopify/draggable库在模块导入阶段就会尝试访问window对象(比如库内部的浏览器环境检测逻辑写在模块顶层),而非等到你在useEffect中调用它时才执行相关代码。哪怕你在useEffect里加了window判断,服务端渲染时解析import语句的阶段就已经触发了错误。

解决方案

1. 组件内动态导入库

直接在useEffect中动态导入@shopify/draggable,确保仅在客户端环境执行导入操作:

function DraggableContainer() {
  useEffect(() => {
    const initDraggable = async () => {
      // 动态导入库,仅在客户端执行
      const { Draggable } = await import('@shopify/draggable');
      
      // 初始化拖拽逻辑
      const draggableInstance = new Draggable(document.querySelectorAll('.draggable-group'), {
        draggable: '.draggable-item'
      });

      // 绑定拖拽事件
      draggableInstance.on('drag:start', () => {
        console.log('拖拽开始');
      });
    };

    initDraggable();
  }, []);

  return (
    <div className="draggable-group">
      <div className="draggable-item">拖拽项1</div>
      <div className="draggable-item">拖拽项2</div>
    </div>
  );
}

export default DraggableContainer;

2. 全局禁用组件的服务端渲染

如果你的拖拽逻辑集中在某个独立组件中,可以用NextJS的dynamic函数导入该组件,并禁用服务端渲染:

import dynamic from 'next/dynamic';

// 动态导入组件,ssr: false 确保仅在客户端渲染
const DraggableContainer = dynamic(() => import('./DraggableContainer'), {
  ssr: false,
});

function HomePage() {
  return (
    <div>
      <h1>首页</h1>
      <DraggableContainer />
    </div>
  );
}

export default HomePage;

为什么之前的方法无效?

你之前在useEffect中判断window并调用库,但import { Draggable } from '@shopify/draggable'语句会在组件初始化时(服务端渲染阶段)就执行,此时服务端没有window对象,库的顶层代码直接触发错误,根本轮不到useEffect执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:40:54