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.