Docs
Editor Basics
Editor Setup

TODO: [ ] expose / document hooks [ ] document events [ ] explain controlled / uncontrolled

Editor Setup

While BlockNote is ready to use out-of-the-box, there are a number of setup options you can choose to fit your use case.

Creating the Editor

Using a React Hook

Most of the time, you'll want to create the BlockNote editor using the useCreateBlockNote hook. This will create a new editor when your React component gets mounted, and accepts a dependency array as with other React hooks.

useCreateBlockNote = (
  options?: Partial<BlockNoteEditorOptions>,
  deps?: React.DependencyList,
) => BlockNoteEditor;

Read on to Options to see what options you can pass to the editor.

Using a Method

You can also create a new editor using BlockNoteEditor.create. You should use this when you want to wait after your React component gets mounted before creating the editor.

BlockNoteEditor.create = (options?: Partial<BlockNoteEditorOptions>) =>
  BlockNoteEditor;

In the demo below, we use BlockNoteEditor.create so we can fetch the editor's initial content from localStorage before creating it.

import { BlockNoteEditor, PartialBlock } from "@blocknote/core";
import { BlockNoteView } from "@blocknote/react";
import "@blocknote/react/style.css";
import { useEffect, useMemo, useState } from "react";
 
async function saveToStorage(jsonBlocks: any[]) {
  // Save contents to local storage. You might want to debounce this or replace with a call to your API / database
  localStorage.setItem("editorContent", JSON.stringify(jsonBlocks));
}
 
async function loadFromStorage() {
  // Gets the previously stored editor contents
  const storageString = localStorage.getItem("editorContent");
  return storageString
    ? (JSON.parse(storageString) as PartialBlock[])
    : undefined;
}
 
export default function App() {
  const [initialContent, setInitialContent] = useState<
    PartialBlock[] | undefined | "loading"
  >("loading");
 
  // Loads the previously stored editor contents
  useEffect(() => {
    loadFromStorage().then((content) => {
      setInitialContent(content);
    });
  }, []);
 
  // Creates a new editor instance.
  // We use useMemo + createBlockNoteEditor instead of useCreateBlockNote so we can delay the creation of the editor until the initial content is loaded.
  const editor = useMemo(() => {
    if (initialContent === "loading") {
      return undefined;
    }
    return BlockNoteEditor.create({ initialContent });
  }, [initialContent]);
 
  if (editor === undefined) {
    return "Loading content...";
  }
 
  // Renders the editor instance.
  return (
    <BlockNoteView
      editor={editor}
      onChange={() => {
        saveToStorage(editor.topLevelBlocks);
      }}
    />
  );
}
 

Read on to Options to see what options you can pass to the editor.

Options

There are a number of options that you can pass to useCreateBlockNote() and BlockNoteEditor.create. You can find the full list of these below:

export type BlockNoteEditorOptions = Partial<{
  initialContent: PartialBlock[];
  domAttributes: Record<string, string>;
  slashMenuItems: ReactSlashMenuItem[];
  defaultStyles: boolean;
  uploadFile: (file: File) => Promise<string>;
  collaboration: CollaborationOptions;
  blockSpecs: BlockSpecs;
  inlineContentSpecs: InlineContentSpecs;
  styleSpecs: StyleSpecs;
}>;

initialContent: The content that should be in the editor when it's created, represented as an array of partial block objects.

domAttributes: An object containing HTML attributes that should be added to various DOM elements in the editor. See Adding DOM Attributes for more.

slashMenuItems: The commands that are listed in the editor's Slash Menu. If this option isn't defined, a default list of commands is loaded.

defaultStyles: Whether to use the default font and reset the styles of <p>, <li>, <h1>, etc. elements that are used in BlockNote. Defaults to true if undefined.

uploadFile: A function which handles file uploads and eventually returns the URL to the uploaded file. Used by the Image Toolbar.

collaboration: Options for enabling real-time collaboration. See Collaboration for more info.

blockSpecs (advanced): advanced Specifications for Custom Blocks. See Block Specs more info.

inlineContentSpecs (advanced): Specifications for Custom Inline Content. See Inline Content Specs for more info.

styleSpecs (advanced): Specifications for Custom Styles. See Style Specs for more info.

Rendering the Editor

Using a React Component

To, render the editor, you should use the BlockNoteView component, and pass in the editor created using useCreateBlockNote or BlockNoteEditor.create:

const editor = useCreateBlockNote();
 
return <BlockNoteView editor={editor} />;

Props

There are a number of additional props you can pass to BlockNoteView. You can find the full list of these below:

export type BlockNoteViewProps = Partial<{
  formattingToolbar?: boolean;
  hyperlinkToolbar?: boolean;
  sideMenu?: boolean;
  slashMenu?: boolean;
  imageToolbar?: boolean;
  tableHandles?: boolean;
  theme:
    | "light"
    | "dark"
    | Theme
    | {
        light: Theme;
        dark: Theme;
      };
  editable?: boolean;
  onSelectionChange?: () => void;
  onChange?: () => void;
}>;

formattingToolbar: Whether the Formatting Toolbar should be enabled.

hyperlinkToolbar: Whether the Hyperlink Toolbar should be enabled.

sideMenu: Whether the Block Side Menu should be enabled.

slashMenu: Whether the Slash Menu should be enabled.

imageToolbar: Whether the Image Toolbar should be enabled.

tableHandles: Whether the Table Handles should be enabled.

theme: The editor's theme, see Themes for more about this.

editable: Whether the editor should be editable.

onSelectionChange: Callback for when the editor selection changes.

onChange: Callback for when the editor selection or content changes.

BlockNoteView also takes props that you can pass to any HTML div element.