Parsing Markdown 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 Markdown 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 initialMarkdown = "Hello, **world!**";export default function App() { // Creates a new editor instance. const editor = useCreateBlockNote(); const markdownInputChanged = useCallback( async (e: ChangeEvent<HTMLTextAreaElement>) => { // Whenever the current Markdown content changes, converts it to an array of // Block objects and replaces the editor's content with them. const blocks = await editor.tryParseMarkdownToBlocks(e.target.value); editor.replaceBlocks(editor.document, blocks); }, [editor], ); // For initialization; on mount, convert the initial Markdown to blocks and replace the default editor's content useEffect(() => { async function loadInitialHTML() { const blocks = await editor.tryParseMarkdownToBlocks(initialMarkdown); editor.replaceBlocks(editor.document, blocks); } loadInitialHTML(); }, [editor]); // Renders the Markdown input and editor instance. return ( <div className="views"> <div className="view-wrapper"> <div className="view-label">Markdown Input</div> <div className="view"> <code> <textarea defaultValue={initialMarkdown} onChange={markdownInputChanged} /> </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%;}