NextJS TypeScript报错:ReferenceError: document is not defined 求助
解决Next.js TypeScript项目中
document is not defined错误 问题原因
Next.js App Router 默认将组件视为服务端组件(Server Component),服务端运行环境中不存在document、window这类浏览器专属的DOM API,直接在组件顶层访问这些API会抛出ReferenceError。
解决方案
以下是几种可行的解决方式,根据你的组件场景选择:
1. 将组件标记为客户端组件
在StarrySky.tsx文件顶部添加'use client'指令,强制组件在浏览器端渲染,此时就能正常访问document和window:
'use client'; import { useEffect, useState } from 'react'; export default function StarrySky() { const [vw, setVw] = useState(0); useEffect(() => { // 初始化视口宽度 const updateViewportWidth = () => { const width = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0); setVw(width); }; updateViewportWidth(); // 监听窗口大小变化,实时更新 window.addEventListener('resize', updateViewportWidth); // 组件卸载时移除监听 return () => window.removeEventListener('resize', updateViewportWidth); }, []); // 后续业务逻辑使用vw变量 return <div className="starry-sky">...</div>; }
适用场景:组件本身需要交互、依赖浏览器API,或大部分逻辑在客户端执行。
2. 动态导入组件并禁用SSR
如果不想将整个组件改为客户端组件,可通过Next.js的dynamic导入函数,指定该组件仅在客户端渲染:
// 在resume/page.tsx中修改导入方式 import dynamic from 'next/dynamic'; // 禁用SSR,组件仅在浏览器加载 const StarrySky = dynamic(() => import('../StarrySky'), { ssr: false }); export default function ResumePage() { return ( <div> <StarrySky /> {/* 页面其他服务端渲染内容 */} </div> ); }
适用场景:组件仅需客户端渲染,而页面其余部分保持服务端渲染以优化性能。
3. 条件判断浏览器环境
如果只是局部代码需要访问浏览器API,可通过typeof window !== 'undefined'判断环境,确保代码仅在浏览器执行:
// StarrySky.tsx中 import { useEffect, useState } from 'react'; export default function StarrySky() { const [vw, setVw] = useState(0); useEffect(() => { if (typeof window !== 'undefined') { const updateWidth = () => { const width = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0); setVw(width); }; updateWidth(); window.addEventListener('resize', updateWidth); return () => window.removeEventListener('resize', updateWidth); } }, []); return <div>...</div>; }
适用场景:组件大部分逻辑可在服务端执行,仅小部分依赖浏览器API。
注意事项
- 避免在组件顶层直接访问
document/window:即使是客户端组件,也建议将这类代码放在useEffect或事件回调中,确保DOM已准备就绪。 - 客户端组件会增加客户端负载:仅在必要时使用
'use client',优先保持服务端组件以优化页面加载性能。
内容的提问来源于stack exchange,提问作者Rzeyee
相关产品推荐
相关产品推荐

