skip to Main Content

I have a big application that I’m building with Next.js for SEO and performance purposes, and there’s a super interactive part of this application that needs a Text Editor (such as Quill.js or Draft.js) where data in it is synced between two users using Socket.io.

The problem is I can’t get a Text Editor to work with Next.js.

When I import Quill, it says ‘Document is not defined’ because there’s no document on the server. With Draft.js, it simply doesn’t render anything but there’s no errors.

Here’s my code for Draft.js:

import { EditorState, convertToRaw, convertFromRaw } from 'draft-js'


class TextEditor extends Component {
  constructor(props) {
    super(props);
    this.state = {
      editorState: EditorState.createWithContent(convertFromRaw(props.contentState))
    }
  }
  static async getInitialProps ({ query, req }) {
    return { contentState: convertToRaw(EditorState.createEmpty().getCurrentContent()) }
  }
  render() {
    console.log('init',this.props.editorState);
    return (
      <div>
        <h1>Test Editor</h1>
        <Editor
          editorState={ this.props.editorState }
        />
      </div>
    );
  }
}

Any help?

2

Answers


  1. Here is my simply component is working with NextJS and React Hook Form

    import React, { useEffect } from "react";
    import { Editor, EditorState, ContentState, convertFromRaw } from "draft-js";
    import "draft-js/dist/Draft.css";
    
    export { EditorState, ContentState };
    
    interface PropTypes {
      name?: string;
      value?: string;
      onChange?: Function;
    }
    
    // Trick to fix issue with NextJS https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/universal/editor.js
    const emptyContentState = convertFromRaw({
      entityMap: {},
      blocks: [
        {
          text: "",
          key: "foo",
          type: "unstyled",
          entityRanges: [],
        },
      ],
    });
    
    function RichTextEditor({ name, value, onChange }: PropTypes) {
      const [editorState, setEditorState] = React.useState(
        EditorState.createWithContent(emptyContentState)
      );
    
      useEffect(() => {
        setEditorState(
          EditorState.createWithContent(ContentState.createFromText(value))
        );
      }, []);
    
      return (
        <Editor
          editorKey={name}
          editorState={editorState}
          onChange={(editorState) => {
            setEditorState(editorState);
    
            onChange(editorState.getCurrentContent().getPlainText());
          }}
          userSelect="none"
          contentEditable={false}
        />
      );
    }
    
    export default RichTextEditor;
    
    
    <Controller
     as={RichTextEditor}
     name="description"
     control={control}
     defaultValue=""
    />
    
    Login or Signup to reply.
  2. Use sun editor. This one is really flexible and compatible with nextjs.
    https://www.npmjs.com/package/suneditor-react
    npm i suneditor suneditor-react

    import dynamic from "next/dynamic";
    import 'suneditor/dist/css/suneditor.min.css'; // Import Sun Editor's CSS File to the _app.js
    
    const SunEditor = dynamic(() => import("suneditor-react"), { //besure to import dynamically
      ssr: false,
    });
    
    const MyComponent = props => {
      return (
        <div>
          <p> My Other Contents </p>
          <SunEditor />
        </div>
      );
    };
    export default MyComponent;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search