Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: element with ID «editorjs» is missing. Pass correct holder's ID. #225

Open
Ivaneyko opened this issue Feb 8, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@Ivaneyko
Copy link

Ivaneyko commented Feb 8, 2023

Environment

  • @editorjs/editorjs version: 2.26.4
  • react-editor-js version: 2.1.0
  • react version: 18.2.0
  • react-dom version: 18.2.0

Code

const EditorInput = forwardRef<any, Props>(({
  label, id = '#', value, onChange, required, error, helperText, margin = 'normal',
  readOnly = false, minHeight = 32
}, ref) => {
  const instanceRef = useRef<any>(null);

  const handleInitialize = useCallback((instance:any) => {
    instanceRef.current = instance;
  }, []);

  const handleChange = async () => {
    const editorData = await instanceRef?.current?.save();

    if ( onChange ) onChange(editorData);
  }

  return (
     <ReactEditorJS
         tools={EDITOR_TOOLS}
         defaultValue={value}
         onInitialize={handleInitialize}
         onChange={handleChange}
         readOnly={readOnly}
         minHeight={minHeight}
         holder="editorjs"
     ><div id="editorjs" /></ReactEditorJS>
  )
});

Describe

Trying with and without custom holder.
This happens when you go to the page where it is editor located. When loading a page directly, this does not always happen

image

@Ivaneyko Ivaneyko added the bug Something isn't working label Feb 8, 2023
@Aldar0K
Copy link

Aldar0K commented Feb 10, 2023

I have the same problem

@steebchen
Copy link

This happens all the time with NextJS

@gediminastub
Copy link

This helps:
https://stackoverflow.com/questions/67688118/unhandled-rejection-error-element-with-id-editorjs-is-missing-pass-correct

@orbachar
Copy link

same issue here without SSR

@adityakumarcodes
Copy link

adityakumarcodes commented Feb 13, 2025

Can anyone please share the workaround for this issue when changing page it is coming everytime.I tried creating a client Editor component,and did a dynamic nossr import in the page to be used but still facing the issue. I am using NextJS

'use client'
import { EDITOR_JS_TOOLS } from '@/lib/editorConfig';
import { createClient } from '@/lib/supabase/client';
import { useEffect, useRef, useState } from 'react';
import { toast } from 'react-toastify';
import EditorJS, { OutputData } from '@editorjs/editorjs';

const INITIAL_DATA = {
    time: 1701368244004,
    blocks: [
        {
            "type": "header",
            "data": {
                "text": "5 🔑s to a longer life ",
                "level": 1
            }
        },
        {
            "id": "zbGZFPM-iI",
            "type": "paragraph",
            "data": {
                "text": "Hey. Meet the new Editor. On this page you can see it in action — try to edit this text. Source code of the page contains the example of connection and configuration."
            }
        },
        {
            "id": "qYIGsjS5rt",
            "type": "header",
            "data": {
                "text": "Key features",
                "level": 3
            }
        },
        {
            "id": "XV87kJS_H1",
            "type": "list",
            "data": {
                "style": "unordered",
                "items": [
                    "It is a block-styled editor",
                    "It returns clean data output in JSON",
                    "Designed to be extendable and pluggable with a simple API"
                ]
            }
        },
        {
            "id": "AOulAjL8XM",
            "type": "header",
            "data": {
                "text": "What does it mean «block-styled editor»",
                "level": 3
            }
        },
        {
            "id": "cyZjplMOZ0",
            "type": "paragraph",
            "data": {
                "text": "Workspace in classic editors is made of a single contenteditable element, used to create different HTML markups. Editor.js <mark class=\"cdx-marker\">workspace consists of separate Blocks: paragraphs, headings, images, lists, quotes, etc</mark>. Each of them is an independent contenteditable element (or more complex structure) provided by Plugin and united by Editor's Core."
            }
        },
        {
            "type": "delimiter",
            "data": {}
        },
    ],
    version: "2.30.8",
};

interface EditorProps {
    initialData?: OutputData;
    id: number;
}


const MyTextEditor: React.FC<EditorProps> = ({ initialData, id }) => {
    const editorInstance = useRef<EditorJS | null>(null);
    const [editorData, setEditorData] = useState(initialData);
    const [isReadOnly, setIsReadOnly] = useState(true);

    useEffect(() => {

        const editor = new EditorJS({
            holder: "editorjs",
            tools: EDITOR_JS_TOOLS,
            data: editorData || INITIAL_DATA,
            onReady: () => {
                console.log("Editor.js is ready to work!");
                editorInstance.current = editor;
            },
            placeholder: "Type '/' for commands",
            readOnly: isReadOnly,
        });


        return () => {
            if (editorInstance.current) {
                editorInstance.current?.destroy();
                editorInstance.current = null;
            }
        };
    }, [initialData, isReadOnly]);

    const extractHeader = (data: OutputData) => {
        const firstBlock = data['blocks']?.[0];
        return firstBlock?.type === "header" ? firstBlock.data.text : null;
    };

    const handleSave = async () => {
        if (editorInstance.current) {
            const data = await editorInstance.current.save();
            setEditorData(data)
            const title = extractHeader(data) || `Note_${id}`;
            const supabase = createClient();
            const { error } = await supabase
                .from('notes')
                .update({ content: data, title: title })
                .eq('id', id);

            if (error) {
                console.error("Error updating content:", error);
                toast.error("Failed to save data!");
            } else {
                toast.success("Content saved successfully!");
            }
        }

        toggleReadOnly();
    };


    const toggleReadOnly = async () => {
        if (editorInstance.current) {
            await editorInstance.current.readOnly.toggle();
            setIsReadOnly((prev) => !prev);
            console.log("Read-Only Mode:", !isReadOnly);
        }

    };

    return <div className="p-2 text-left">
        <button className="btn" onClick={handleSave} disabled={isReadOnly}>
            Save
        </button>
        <button className="btn" onClick={toggleReadOnly}>
            {isReadOnly ? "Edit" : "Read"}
        </button>
        <div className="px-2 py-2" id='editorjs' />
        {/* <Image src='https://cdn.pixabay.com/photo/2023/07/31/16/37/sugar-apple-8161386_1280.jpg' alt={''} width={500} height={50} className='overflow-clip rounded-md object-fit m-6' /> */}
    </div>

}

export default MyTextEditor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants