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

在Next.js项目中集成React Quill ImageResize模块时遇window未定义错误

解决Next.js中React Quill添加ImageResize模块时的window未定义问题

问题根源:Next.js是服务端渲染(SSR),服务端环境不存在window对象。你当前代码里直接在顶层导入ImageResize和Quill并执行注册,这部分逻辑会在服务端运行,所以触发ReferenceError: window is not defined。

修复步骤:

  1. 把ImageResize的导入和Quill注册放到客户端环境执行
    利用Next.js的dynamic导入,在加载ReactQuill的同时,仅在客户端完成ImageResize模块的注册。
  2. 避免在服务端访问Quill相关API
    调整modules配置中parchment的获取方式,确保只在客户端执行。

修改后的完整代码:

import { useState, useEffect } from 'react'
import dynamic from 'next/dynamic'
import 'react-quill/dist/quill.snow.css'
import styles from '../styles/Components/TextEditor.module.scss'

// 动态导入ReactQuill,同时在客户端注册ImageResize模块
const ReactQuill = dynamic(() => 
  import('react-quill').then(async (mod) => {
    const Quill = mod.Quill
    // 仅在客户端导入并注册ImageResize
    const ImageResize = (await import('quill-image-resize-module-react')).default
    Quill.register('modules/imageResize', ImageResize)
    return mod
  }), 
  { ssr: false }
)

interface TextEditorParams {
  onChange: (value: string) => string | void
  placeholder?: string
  error?: boolean
  defaultValue?: string | undefined
  required?: boolean
}

const TextEditor = ({
  onChange,
  placeholder,
  error,
  defaultValue,
  required
}: TextEditorParams) => {
  const [errorState, setErrorState] = useState<boolean | undefined>(false)
  const [modules, setModules] = useState<any>(null)

  useEffect(() => {
    let shouldUpdate = true
    if (shouldUpdate) {
      setErrorState(error)
    }

    return () => {
      shouldUpdate = false
    }
  }, [error])

  // 在客户端初始化modules配置,确保Quill已加载
  useEffect(() => {
    import('react-quill').then(({ Quill }) => {
      setModules({
        toolbar: {
          container: [
            [{ header: [1, 2, 3, 4, 5, 6, false] }],
            ['bold', 'italic', 'underline', 'strike'],
            [{ list: 'ordered' }, { list: 'bullet' }],
            [{ align: [] }],
            ['link', 'image'],
            ['clean']
          ]
        },
        imageResize: {
          parchment: Quill.import('parchment'),
          modules: ['Resize', 'DisplaySize', 'Toolbar']
        }
      })
    })
  }, [])

  const changeValue = (value: string) => {
    onChange(value)
  }

  // 确保modules加载完成后再渲染ReactQuill
  if (!modules) return null

  return (
    <div className={styles.editor}>
      <ReactQuill
        modules={modules}
        defaultValue={defaultValue}
        onChange={(value) => changeValue(value)}
        placeholder={`${placeholder} ${required ? '*' : ''}`}
        className={errorState ? 'textEditor__error' : 'textEditor'}
      />
    </div>
  )
}

export default TextEditor

关键修改说明:

  • 把ImageResize的导入和Quill.register放到dynamic导入ReactQuill的回调里,用async/await确保执行顺序,同时dynamic设置ssr: false,这部分逻辑只会在客户端执行。
  • 用useState保存modules配置,在useEffect里(客户端环境)初始化,避免在服务端访问Quill.import。
  • 渲染时先判断modules是否存在,避免ReactQuill加载前传入未定义的modules。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 05:45:32