NextJS出现ReferenceError: document is not defined错误求助
解决Next.js中
ReferenceError: document is not defined错误(使用react-quill时) 错误原因
你碰到的ReferenceError: document is not defined是因为Next.js默认的服务端渲染(SSR)环境里不存在浏览器专属的document对象。你的代码里直接在顶层导入了Quill(import { Quill } from "react-quill"),这部分代码会在服务端执行,而Quill初始化时依赖浏览器的DOM环境,所以触发了错误。虽然你用dynamic导入ReactQuill时关闭了SSR,但Quill的导入和后续的主题注册代码还是在服务端运行了,这才是问题根源。
解决方案
核心思路是:所有依赖浏览器DOM的代码,必须确保只在客户端环境执行,避开服务端渲染阶段。下面提供两种可行的修改方式:
方式一:在useEffect中封装Quill主题逻辑
把Quill的导入、主题扩展和注册逻辑放到useEffect钩子中,利用typeof window !== 'undefined'判断确保只在浏览器端执行:
import { useEffect } from "react"; import dynamic from 'next/dynamic'; import toolbarOptions from "./toolbar"; import 'react-quill/dist/quill.bubble.css'; import styles from '../styles/Home.module.css' const ReactQuill = dynamic(() => import("react-quill"), { ssr: false }); export default function Home() { useEffect(() => { // 仅在客户端环境执行Quill相关操作 if (typeof window !== 'undefined') { const { Quill } = require("react-quill"); const BubbleTheme = Quill.import("themes/bubble"); class ExtendBubbleTheme extends BubbleTheme { constructor(quill, options) { super(quill, options); quill.on("selection-change", (range) => { if (range) { quill.theme.tooltip.show(); quill.theme.tooltip.position(quill.getBounds(range)); } }); } } Quill.register("themes/bubble", ExtendBubbleTheme); } }, []); return ( <div className={styles.container}> <h1>Quill Editor</h1> <ReactQuill theme="bubble" placeholder="Compose an epic..." modules={{ toolbar: toolbarOptions }} /> </div> ) }
方式二:封装Quill主题模块并动态导入
- 新建
quill-theme.js文件,把主题扩展逻辑单独封装:
import { Quill } from "react-quill"; const BubbleTheme = Quill.import("themes/bubble"); class ExtendBubbleTheme extends BubbleTheme { constructor(quill, options) { super(quill, options); quill.on("selection-change", (range) => { if (range) { quill.theme.tooltip.show(); quill.theme.tooltip.position(quill.getBounds(range)); } }); } } Quill.register("themes/bubble", ExtendBubbleTheme);
- 在页面组件中动态导入该模块:
import { useEffect } from "react"; import dynamic from 'next/dynamic'; import toolbarOptions from "./toolbar"; import 'react-quill/dist/quill.bubble.css'; import styles from '../styles/Home.module.css' const ReactQuill = dynamic(() => import("react-quill"), { ssr: false }); export default function Home() { useEffect(() => { // 动态加载Quill主题模块,确保只在客户端执行 const loadTheme = async () => { await import('./quill-theme'); }; loadTheme(); }, []); return ( <div className={styles.container}> <h1>Quill Editor</h1> <ReactQuill theme="bubble" placeholder="Compose an epic..." modules={{ toolbar: toolbarOptions }} /> </div> ) }
关键说明
两种方式本质都是让Quill相关的DOM依赖代码避开服务端渲染阶段,只在浏览器环境中运行,这样就不会再触发document is not defined的错误了。
内容的提问来源于stack exchange,提问作者Kia Kalista
相关产品推荐
相关产品推荐

