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

Next.js报错ReferenceError: window is not defined 解决方案咨询

报错原因

Next.js 默认会在 Node.js 服务端完成组件/页面的预渲染流程,服务端运行环境不存在浏览器专属的window、document等全局API。
你当前把访问window.location的逻辑写在了模块顶层,代码在服务端编译执行阶段就会触发这行逻辑,直接抛出ReferenceError: window is not defined。
你之前注释掉的存在性判断思路是对的,但在if块内用const声明的变量是块级作用域,块外的组件代码根本访问不到code变量,就算取消注释也会触发新的未定义错误。

相关报错截图:
报错信息截图

修复方案

根据你的使用场景选一种即可:

  • 方案1:把window相关逻辑移到仅客户端执行的生命周期里(通用兼容写法,全Next.js版本可用)
    useEffect内的代码只会在客户端hydration完成后执行,不会在服务端运行,从根源避免访问不到window的问题,参考修改后的代码:
    import React, { createContext, useState, useContext, useEffect } from "react";
    import useAuth from '../hooks/useAuth';
    import axios from "axios";
    
    export const SpotifyContext = createContext()
    
    function SpotifyProvider({ children }){
        const [code, setCode] = useState(null)
        
        useEffect(() => {
            // 此处代码仅客户端运行,可安全访问window
            const urlCode = new URLSearchParams(window.location.search).get("code")
            setCode(urlCode)
        }, [])
    
        const { accessToken, connecting, SignOut, error, setError, tokenExpired } = useAuth(code)
    
        const headers = {
            Authorization: `Bearer ${accessToken}`,
            'Content-Type': 'application/json',
        }
    
        // 原有组件剩余逻辑...
    }
    
  • 方案2:用Next.js官方路由API获取查询参数(推荐,框架原生兼容SSR)
    不需要自己手动访问window.location,框架封装的钩子已经做了服务端兼容:
    • 如果你用Next.js 13+ App Router,首先在文件顶部加'use client'指令(Context Provider必须是客户端组件),然后用useSearchParams取值:
      'use client'
      import { useSearchParams } from 'next/navigation'
      
      function SpotifyProvider({ children }){
          const searchParams = useSearchParams()
          const code = searchParams.get('code')
          // 剩余原有逻辑...
      }
      
    • 如果你用Pages Router,直接用useRouter取query参数即可:
      import { useRouter } from 'next/router'
      
      function SpotifyProvider({ children }){
          const router = useRouter()
          const code = router.query.code
          // 剩余原有逻辑...
      }
      
  • 方案3:修正顶层判断的作用域问题(快速修复,不推荐用于依赖参数渲染内容的场景)
    把变量声明提到判断外面,避免块级作用域导致的访问问题:
    const code = typeof window !== "undefined" 
      ? new URLSearchParams(window.location.search).get("code") 
      : null
    

    注意:这种写法下服务端拿到的code永远是null,如果组件首屏渲染内容依赖code的值,大概率会出现服务端和客户端渲染内容不一致的hydration报错,非必要不选这个方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 05:01:00