Parsing HTML to Blocks
This example shows how you can convert HTML content to a BlockNote document.
Note that the editor itself is locked for editing by setting editable to false.
Try it out: Edit the HTML in the textarea to see the BlockNote document update!
Relevant Docs:
import "@blocknote/core/fonts/inter.css";import { useCreateBlockNote } from "@blocknote/react";import { BlockNoteView } from "@blocknote/mantine";import "@blocknote/mantine/style.css";import { ChangeEvent, useCallback, useEffect } from "react";import "./styles.css";const initialHTML = "<p>Hello, <strong>world!</strong></p>";export default function App() { // Creates a new editor instance. const editor = useCreateBlockNote(); const htmlInputChanged = useCallback( async (e: ChangeEvent<HTMLTextAreaElement>) => { // Whenever the current HTML content changes, converts it to an array of // Block objects and replaces the editor's content with them. const blocks = await editor.tryParseHTMLToBlocks(e.target.value); editor.replaceBlocks(editor.document, blocks); }, [editor], ); // For initialization; on mount, convert the initial HTML to blocks and replace the default editor's content useEffect(() => { async function loadInitialHTML() { const blocks = await editor.tryParseHTMLToBlocks(initialHTML); editor.replaceBlocks(editor.document, blocks); } loadInitialHTML(); }, [editor]); // Renders the HTML input and editor instance. return ( <div className="views"> <div className="view-wrapper"> <div className="view-label">HTML Input</div> <div className="view"> <code> <textarea defaultValue={initialHTML} onChange={htmlInputChanged} /> </code> </div> </div> <div className="view-wrapper"> <div className="view-label">Editor Output</div> <div className="view"> <BlockNoteView editor={editor} editable={false} /> </div> </div> </div> );}.views { container-name: views; container-type: inline-size; display: flex; flex-direction: row; flex-wrap: wrap; gap: 8px; height: 100%; padding: 8px;}.view-wrapper { display: flex; flex-direction: column; height: calc(50% - 4px); width: 100%;}@container views (width > 1024px) { .view-wrapper { height: 100%; width: calc(50% - 4px); }}.view-label { color: #0090ff; display: flex; font-size: 12px; font-weight: bold; justify-content: space-between; margin-inline: 16px;}.view { border: solid #0090ff 1px; border-radius: 16px; flex: 1; height: 0; padding: 8px;}.view .bn-container { height: 100%; margin: 0; max-width: none; padding: 0;}.view .bn-editor { height: 100%; overflow: auto;}.view textarea { background-color: #0090ff20; border: none; border-radius: 8px; flex: 1; height: 100%; margin: 0; overflow: auto; padding: 8px; resize: none; white-space: pre-wrap; width: 100%;}