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

NextJS深度链接/页面刷新时全局变量丢失问题咨询

问题与解决方案

问题描述

在Next.js的Pages/_document.tsx中引入了全局配置脚本,脚本会在window对象上设置全局变量。首页加载正常,但嵌套路由页面刷新或通过深度链接访问时,抛出ReferenceError: window is not defined错误。需求为仅在客户端使用该配置,且不想在构建阶段打包配置变量,希望发布时直接更新变量,询问当前方案是否可行及解决办法。

对应的代码实现:

import Script from 'next/script'
...
...
render() {
  return (
    <Html lang='en'>
      <Head>
        <meta charSet='UTF-8' />
        <meta httpEquiv='X-UA-Compatible' content='IE=edge' />
      </Head>
      <body>
        <Main />
        <NextScript />
        <Script src='/scripts/public-config.js' strategy='beforeInteractive' />
      </body>
    </Html>
  )
}

解决方案

你的核心方案思路是可行的,问题出在脚本加载策略和window访问时机上,调整后就能满足需求:

  • 更换脚本加载策略:将strategy='beforeInteractive'改为strategy='afterInteractive'或strategy='lazyOnload'。beforeInteractive会在服务端渲染阶段尝试加载脚本,此时不存在window对象才导致报错;后两种策略仅在客户端环境执行,能彻底避免服务端层面的报错。

  • 确保客户端才访问全局变量:业务代码中使用window上的配置时,先做客户端环境判断:

    // 组件内使用示例
    if (typeof window !== 'undefined') {
      const appConfig = window.publicConfig;
      // 后续业务逻辑
    }
    

    或者利用Next.js的useEffect钩子(该钩子仅在客户端执行):

    import { useEffect } from 'react';
    
    function TargetComponent() {
      useEffect(() => {
        const appConfig = window.publicConfig;
        // 在这里处理配置相关逻辑
      }, []);
      // 组件其他内容
    }
    
  • 脚本放置位置优化:可以把<Script>标签移到_app.tsx中而非_document.tsx。_app.tsx的逻辑更偏向客户端,能更合理地控制脚本加载时机,同时完全不影响你在发布阶段替换public-config.js文件的需求——只要构建产物中该脚本是独立文件,发布时直接替换即可,无需重新构建整个应用。

调整后既能满足客户端加载配置、发布时动态更新变量的需求,又能彻底解决服务端渲染的window未定义错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:55:27