Next.js使用editorjs-react-renderer新版本SSG渲染报错求助
解决editorjs-react-renderer升级后Next.js中document API报错问题
问题根源
新版本的editorjs-react-renderer在初始化或渲染逻辑中直接调用了浏览器专属的document.implementation.createHTMLDocument API,而Next.js在服务端渲染(包括SSG)阶段不存在document对象;即使是非SSG页面,组件初始化时的服务端预渲染阶段也会触发该API,导致报错。旧版本2.7.3因内部做了SSR兼容处理,所以没有这个问题。
解决方案
1. 动态导入组件,强制仅在客户端渲染
使用Next.js的next/dynamic工具,将editorjs-react-renderer标记为不参与服务端渲染,确保所有依赖浏览器API的逻辑只在客户端执行:
import dynamic from 'next/dynamic'; // 动态导入组件,禁用服务端渲染 const EditorJSRenderer = dynamic(() => import('editorjs-react-renderer'), { ssr: false, loading: () => <p>加载中...</p> // 可选:设置加载状态 }); // 在页面中使用组件 export default function MyPage({ editorData }) { return <EditorJSRenderer data={editorData} />; }
2. 为自定义渲染器添加环境判断
如果需要自定义渲染器,通过typeof window !== 'undefined'判断环境,确保依赖浏览器API的逻辑仅在客户端执行:
import { render } from 'editorjs-react-renderer'; const customRenderers = { paragraph: (props) => { // 仅在客户端执行依赖document的逻辑 if (typeof window !== 'undefined') { // 这里可安全使用document相关API const element = document.createElement('p'); element.className = 'custom-paragraph'; element.textContent = props.data.text; return element; } // 服务端渲染时返回兼容的静态内容 return <p className="custom-paragraph">{props.data.text}</p>; } };
3. 封装客户端专属的渲染Wrapper
如果动态导入无法满足需求,手动封装组件,利用useEffect确保渲染逻辑仅在客户端执行:
import { useEffect, useState } from 'react'; import { render } from 'editorjs-react-renderer'; const EditorJSRendererWrapper = ({ data, renderers }) => { const [renderedContent, setRenderedContent] = useState(null); useEffect(() => { // useEffect仅在客户端触发,可安全调用依赖document的render方法 const content = render(data, renderers); setRenderedContent(content); }, [data, renderers]); return <>{renderedContent}</>; }; export default EditorJSRendererWrapper;
内容的提问来源于stack exchange,提问作者Hassan Nazar
相关产品推荐
相关产品推荐

