Suneditor React Component
suneditor-react provides a convenient React wrapper for the SunEditor WYSIWYG HTML editor. It simplifies integrating a rich text editor into React applications by encapsulating the underlying SunEditor library within a standard React component interface. The current stable version is 3.6.1, and the project appears to have an active release cadence with regular updates addressing bug fixes, performance improvements, and new features. A key differentiator is its explicit support for Next.js via dynamic imports to handle server-side rendering (SSR) compatibility. It also offers fine-grained control over editor configuration, including language settings, form name integration, and the ability to load only necessary plugins for performance optimization, differentiating it from simpler wrappers that might bundle all features by default. It requires the base `suneditor` package as a peer dependency, giving users control over its version.
Common errors
-
ReferenceError: document is not defined
cause Attempting to render `SunEditor` on the server-side in an SSR environment (e.g., Next.js) without disabling SSR for the component.fixWrap the `SunEditor` component with `next/dynamic` and set `ssr: false`. Example: `const SunEditor = dynamic(() => import('suneditor-react'), { ssr: false });` -
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
cause Forgetting to install the `suneditor` core package, which `suneditor-react` depends on, or an incorrect import statement.fixEnsure both `suneditor` and `suneditor-react` are installed (`npm install suneditor suneditor-react`) and that `SunEditor` is imported correctly as a default import: `import SunEditor from 'suneditor-react';` -
Cannot read properties of undefined (reading 'setContents')
cause Attempting to call methods on the `SunEditor` core instance (e.g., `setContents`, `getContents`) before it has been initialized or when the ref is not correctly pointing to the instance.fixUse the `getSunEditorInstance` prop to obtain the core SunEditor object and store it in a `useRef` hook. Ensure you check if the ref's `current` value is available before attempting to call methods on it.
Warnings
- breaking The order of parameters for `onImageUploadBefore`, `onVideoUploadBefore`, and `onAudioUploadBefore` event handlers was fixed.
- gotcha The `suneditor` core package is a peer dependency and must be installed separately alongside `suneditor-react`.
- gotcha When using Server-Side Rendering (SSR) frameworks like Next.js, importing `SunEditor` directly will cause 'document is not defined' errors during build or server-side execution.
- gotcha Accessing the underlying SunEditor instance (the 'core' object) directly from event callbacks is not supported by `suneditor-react`. You need to use the `getSunEditorInstance` prop.
- gotcha For optimal performance, especially with many plugins, it's recommended to load only the plugins you need.
Install
-
npm install suneditor-react -
yarn add suneditor-react -
pnpm add suneditor-react
Imports
- SunEditor
const SunEditor = require('suneditor-react');import SunEditor from 'suneditor-react';
- SunEditor CSS
import 'suneditor/dist/css/suneditor.min.css';
- SunEditor (Next.js)
import SunEditor from 'suneditor-react';
import dynamic from 'next/dynamic'; const SunEditor = dynamic(() => import('suneditor-react'), { ssr: false }); - SunEditorCore (TypeScript)
import SunEditorCore from 'suneditor/src/lib/core';
Quickstart
import React from 'react';
import dynamic from 'next/dynamic';
import 'suneditor/dist/css/suneditor.min.css'; // Import Sun Editor's CSS File
// Important: Dynamic import for Next.js to disable SSR
const SunEditor = dynamic(() => import('suneditor-react'), {
ssr: false,
});
const MyRichTextEditor = () => {
const editorRef = React.useRef();
// The sunEditor parameter will be set to the core suneditor instance
const getEditorInstance = (sunEditor) => {
editorRef.current = sunEditor;
if (editorRef.current) {
console.log('SunEditor instance ready:', editorRef.current);
// Example: Set initial content programmatically
// editorRef.current.setContents('<p>Hello from <b>suneditor-react</b>!</p>');
}
};
const handleEditorChange = (content) => {
console.log('Editor content changed:', content);
};
return (
<div>
<h1>My Blog Post Editor</h1>
<SunEditor
getSunEditorInstance={getEditorInstance}
onChange={handleEditorChange}
setOptions={{
height: '200px',
buttonList: [['undo', 'redo'], ['font', 'fontSize', 'formatBlock'], ['bold', 'underline', 'italic', 'strike'], ['align', 'list'], ['image', 'link']],
lang: 'en' // Example language setting
}}
defaultValue="<p>Start typing your content here...</p>"
/>
<button onClick={() => console.log('Current content:', editorRef.current?.getContents())}>
Log Current Content
</button>
</div>
);
};
export default MyRichTextEditor;