BlockNote
BlockNote copied to clipboard
Having trouble with autofocus feature - TypeError: Cannot read properties of undefined (reading 'focus')
The editor is typed NonNullable by useCreateBlockNote, but It cannot be accessed (or at least not mounted) on initial hook call.
const editor = useCreateBlockNote({
schema: schema,
initialContent: safevalue(defaultValue),
});
useEffect(() => {
if (!editor) return;
if (!editor.focus) return;
editor.focus();
}, [editor]);
Am I missing something here?
Below will work when called via click event
<div
className="prose dark:prose-invert mx-auto w-full"
onClick={() => editor.focus()}
>
<ThemedRichTextEditorContent
onKeyDown={(e) => {
// this is required for preventing exit on enter pressed
e.stopPropagation();
}}
editor={editor}
/>
</div>
This seems unexpected. Are you using the latest version of BlockNote? Could you perhaps share a Stackblitz reproducing this issue?
I got it to work with the following
useEffect(() => {
if (!editor) return;
if (!editor.prosemirrorView) return;
editor.focus();
}, [editor]);
I suspect the element is not yet fully mounted in OPs example
I've seen this issue crop up a few times recently, it might be worth exposing a hook with this code as it seems like a common use case. Either that, or initialize the editor view synchronously in useCreateBlockNote.
It would be great if there was an autofocus prop which, when true, would also initialize the editor if it is not already initialized and then focus it. The current DX is a bit challenging.
It would be great if supported officialy, but for now - one possible workaround is by busy waiting:
import type { BlockNoteEditor } from '@blocknote/core';
function useFocusOnEditor(editor: BlockNoteEditor) {
useEffect(() => {
const intervalID = setInterval(() => {
if (editor) {
editor.focus(); // This will focus on 1st line, beginning of the editor
clearInterval(intervalID);
}
}, 500); // Adjust the interval as needed
return () => {
clearInterval(intervalID);
};
}, [editor]);
}
For customization such as where to put the cursor's position, it could be done by accessing tiptap's editor instead (although I believe we're not supposed to access it, so it can break in future updates):
// https://tiptap.dev/docs/editor/api/commands/selection/focus
editor._tiptapEditor.commands.focus('end'); // focus at the end