Raden Bagus
Raden Bagus

Reputation: 560

(CKEditor) Window is not defined ReactJS While Implementing

I would like to implement CKEditor into my react project. However, I received an error while trying to load it. I have been following all the official documentation. I have no idea why, anyway here is my code

import React from 'react';

class MyEditor extends React.Component {
    state = {loading: true};

    componentDidMount() {
        this.CKEditor = require("@ckeditor/ckeditor5-react");
        this.ClassicEditor = require("@ckeditor/ckeditor5-build-classic");
        this.setState({ loading: false }); 
    }

    render() {
        return ({this.CKEditor && (<this.CKEditor editor={this.ClassicEditor} data="<p>Hello from CKEditor 5!</p>"
                onInit={ editor => {
                    // You can store the "editor" and use when it is needed.
                    console.log( 'Editor is ready to use!', editor );
                } }
                onChange={ ( event, editor ) => {
                    const data = editor.getData();
                    console.log( { event, editor, data } );
                } }/>)})
    }
}

export default MyEditor;

I receive this following error

ReferenceError: window is not defined at Object. (/Users/bobbyjulian/Desktop/project/test/node_modules/ ckeditor/ckeditor5-react/dist/ckeditor.js:5:244 Module._compile internal/modules/cjs/loader.js:778:30 Module._extensions..js internal/modules/cjs/loader.js:789:10 Module.load internal/modules/cjs/loader.js:653:32 tryModuleLoad internal/modules/cjs/loader.js:593:12

I really appreciate any answer. Thank you.

Upvotes: 8

Views: 10019

Answers (3)

Bill Sourour
Bill Sourour

Reputation: 1186

Here's a working example with NextJS and React Hooks. We can take advantage of useRef to hold on to the Editor instances.

import React, { useState, useEffect, useRef } from 'react'

export default function MyEditor () {
  const editorRef = useRef()
  const [editorLoaded, setEditorLoaded] = useState(false)
  const { CKEditor, ClassicEditor } = editorRef.current || {}

  useEffect(() => {
    editorRef.current = {
      // CKEditor: require('@ckeditor/ckeditor5-react'), // depricated in v3
      CKEditor: require('@ckeditor/ckeditor5-react').CKEditor // v3+
      ClassicEditor: require('@ckeditor/ckeditor5-build-classic')
    }
    setEditorLoaded(true)
  }, [])

  return editorLoaded ? (
    <CKEditor
      editor={ClassicEditor}
      data='<p>Hello from CKEditor 5!</p>'
      onInit={editor => {
        // You can store the "editor" and use when it is needed.
        console.log('Editor is ready to use!', editor)
      }}
      onChange={(event, editor) => {
        const data = editor.getData()
        console.log({ event, editor, data })
      }}
    />
  ) : (
    <div>Editor loading</div>
  )
}

From the docs:

useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.

Upvotes: 31

Him Ho
Him Ho

Reputation: 77

Dynamic import will solve this issue

Upvotes: 1

Vaibhav Singh
Vaibhav Singh

Reputation: 942

If you are doing server side rendering then you need to load your CKeditor dynamically, because it interacts with the DOM thus, on server since there is no browser it throws this Error.

 class MyEditor extends React.Component {
  state = { loading: true };

  componentDidMount() {
    this.CKEditor = require("@ckeditor/ckeditor5-react");
    this.ClassicEditor = require("@ckeditor/ckeditor5-build-classic");
    this.setState({ loading: false });
  }

  render() {
    return this.CKEditor ? (
      <this.CKEditor
        editor={this.ClassicEditor}
        data="<p>Hello from CKEditor 5!</p>"
        onInit={editor => {
          // You can store the "editor" and use when it is needed.
          console.log("Editor is ready to use!", editor);
        }}
        onChange={(event, editor) => {
          const data = editor.getData();
          console.log({ event, editor, data });
        }}
      />
    ) : (
      <div>Editor loading</div>
    );
  }
}

Upvotes: 4

Related Questions