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

NextJS v11.1.12报ReferenceError: document is not defined的原因及解决方法询问

NextJS 出现document is not defined报错的原因与解决方案

报错原因

NextJS默认启用服务端渲染(SSR)/静态站点生成(SSG)能力,代码会先在Node.js服务端环境执行预渲染逻辑,而Node环境中不存在浏览器专属的document、window等全局对象,你直接在组件顶层作用域调用document.querySelector,就会触发ReferenceError: document is not defined报错。
至于之前代码可以正常运行,大概率是此前你临时关闭了对应组件的SSR,或是代码逻辑原本只会在客户端交互时触发,后续缓存或构建规则变动导致这部分DOM操作逻辑被提前到了服务端执行。
另外你原代码的document.querySelector('state-select-dropdown-box')存在语法问题:缺少类选择器的.前缀,会被识别为选择<state-select-dropdown-box>标签,即使解决了document报错也无法选中对应类名的div,需要修改为.state-select-dropdown-box。

解决方案

方案1:将DOM操作放入useEffect钩子(最推荐)

React的useEffect回调只会在客户端组件挂载完成后执行,此时可以正常访问浏览器全局对象,同时更推荐用useRef直接绑定目标DOM,比querySelector更符合React开发规范:

import { useEffect, useRef } from 'react'

const Header = () => {
  // 用useRef绑定目标DOM元素
  const dropDownRef = useRef(null)

  function toggleMenu() {
    // 可选链避免空值报错
    dropDownRef.current?.classList.toggle('show')
  }

  // 如果你一定要用querySelector可以写在useEffect内部
  useEffect(() => {
    const dropDownMenu = document.querySelector('.state-select-dropdown-box')
    console.log(dropDownMenu)
  }, [])

  return (
    <div>
      {/* 给目标div绑定ref */}
      <div ref={dropDownRef} className="state-select-dropdown-box">
        {/* 下拉菜单内容 */}
      </div>
      <button onClick={toggleMenu}>切换菜单</button>
    </div>
  )
}

方案2:前置判断浏览器环境

如果不想修改hooks逻辑,可以在调用document前先判断当前是否为浏览器环境:

const dropDownMenu = typeof window !== 'undefined' ? document.querySelector('.state-select-dropdown-box') : null

注意该方式下服务端渲染阶段拿到的dropDownMenu为null,需要保证调用toggleMenu的逻辑只会在客户端交互时触发。

方案3:关闭组件的SSR能力

如果整个组件都不需要参与服务端渲染,可以用NextJS提供的dynamic方法导入组件并关闭SSR:

// 在引入Header组件的父组件中编写
import dynamic from 'next/dynamic'

const Header = dynamic(() => import('./Header'), { ssr: false })

如果是使用Next 13+的App Router,直接在Header组件顶部加上'use client'指令即可标记为客户端组件,直接访问document不会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:54:04