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

Next.js 14构建报错window is not defined排查求助

解决Next.js 14构建时「ReferenceError: window is not defined」错误

开发环境正常但构建失败,核心原因是服务端渲染阶段执行了依赖浏览器环境(window/navigator等)的代码——即便你没直接写window,依赖的组件、工具函数或hooks也可能触发这个问题。以下是针对性排查和修复方案:

1. 修复copyToClipboard工具函数

LeadCard中调用的copyToClipboard必然依赖浏览器的navigator.clipboard,服务端无此对象。修改函数,添加环境判断:

// @/utils/index.js
export const copyToClipboard = (text) => {
  // 仅在客户端执行
  if (typeof window === 'undefined') return;
  try {
    navigator.clipboard.writeText(text);
  } catch (err) {
    // 可选降级处理
    const textArea = document.createElement('textarea');
    textArea.value = text;
    document.body.appendChild(textArea);
    textArea.select();
    document.execCommand('copy');
    document.body.removeChild(textArea);
  }
};

2. 检查useToast自定义Hook

Toast组件通常需要操作DOM或依赖window,确保Hook内的逻辑仅在客户端执行:

// @/hooks/useToast.js
import { useEffect, useState } from 'react';

export const useToast = () => {
  const [toasts, setToasts] = useState([]);

  // 用useEffect包裹初始化/监听逻辑,确保仅在客户端执行
  useEffect(() => {
    // 比如监听toast自动关闭、绑定DOM事件等
  }, []);

  const showSuccessMessage = (message) => {
    if (typeof window === 'undefined') return;
    setToasts(prev => [...prev, { type: 'success', message }]);
  };

  const showErrorMessage = (message) => {
    if (typeof window === 'undefined') return;
    setToasts(prev => [...prev, { type: 'error', message }]);
  };

  return { showSuccessMessage, showErrorMessage, toasts };
};

3. 确保所有客户端组件添加'use client'

检查@/components/commons下的子组件(如DropdownOverlay、LeadModal、ShareAgreementModal等),如果它们依赖浏览器API,必须在组件顶部添加'use client'指令,避免服务端渲染时执行:

// 示例:DropdownOverlay组件
'use client';

import React from 'react';

const DropdownOverlay = () => {
  // 组件逻辑
};

export default DropdownOverlay;

4. 逐步排查定位问题组件

如果以上修复无效,通过注释法缩小范围:

  • 先将DidNotHire页面中的LeadCard替换为静态内容,执行npm run build,若构建成功则问题出在LeadCard或其子组件;
  • 再逐步注释LeadCard内的功能(比如复制逻辑、Toast调用、Modal组件),每次构建验证,定位到具体触发错误的代码块。

5. 动态导入禁用SSR(兜底方案)

若某些组件无法适配服务端渲染,用Next.js动态导入并禁用SSR:

// 在DidNotHire页面中替换LeadCard的导入
import dynamic from 'next/dynamic';
const LeadCard = dynamic(() => import('@/components/commons/LeadCard'), { ssr: false });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 09:40:58