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

部署至Vercel时出现ReferenceError: window is not defined,本地无此问题

问题分析与修复方案

问题原因

你的代码在初始化useState时直接访问了window.innerWidth和window.innerHeight,而Vercel部署时默认会执行服务器端渲染(SSR)。服务器环境中不存在浏览器的window对象,因此这段代码在服务器执行时会抛出ReferenceError: window is not defined。本地开发通常是纯客户端渲染(CSR),所以不会触发这个错误。

修复方案

核心思路是确保仅在客户端环境中访问window对象,以下是两种可行的修复方式:

方案一:初始化时添加环境判断

在useState初始化时,通过typeof window !== 'undefined'判断当前是否为客户端环境,给服务器端设置一个默认占位值:

export function WindowContextProvider({ children }: WindowContextProviderProps): JSX.Element {
  const [windowSize, setWindowSize] = useState<WindowSize>({
    // 服务器端用默认值,客户端用真实窗口尺寸
    width: typeof window !== 'undefined' ? window.innerWidth : 1200,
    height: typeof window !== 'undefined' ? window.innerHeight : 800,
  });

  useEffect(() => {
    const handleResize = (): void =>
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });

    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);

  const value: WindowContext = {
    ...windowSize,
    isMobile: windowSize.width < 500,
  };

  return <WindowContext.Provider value={value}>{children}</WindowContext.Provider>;
}

方案二:在useEffect中初始化尺寸

useEffect的回调函数只会在客户端执行,因此可以把初始尺寸的设置放在这里,彻底避免服务器端访问window:

export function WindowContextProvider({ children }: WindowContextProviderProps): JSX.Element {
  const [windowSize, setWindowSize] = useState<WindowSize>({
    width: 0,
    height: 0,
  });

  useEffect(() => {
    // 首次加载时先更新一次窗口尺寸
    const updateWindowSize = () => {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    };

    updateWindowSize();
    window.addEventListener("resize", updateWindowSize);
    return () => window.removeEventListener("resize", updateWindowSize);
  }, []);

  // 处理初始值为0的情况,避免isMobile判断异常
  const value: WindowContext = {
    ...windowSize,
    isMobile: windowSize.width > 0 ? windowSize.width < 500 : false,
  };

  return <WindowContext.Provider value={value}>{children}</WindowContext.Provider>;
}

注意事项

  • 方案一的默认值可以根据页面布局自定义,能减少客户端渲染时的布局跳动;
  • 方案二更严谨,但初始状态下windowSize为{width:0, height:0},需要额外处理isMobile的判断逻辑,防止出现错误状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:20:26