Content Formats

Persist Editor content as BlockNote JSON or Markdown.

Overview

Editor.Root has one content API for every supported format:

<Editor.Root
  content={content}
  contentFormat="blocknote"
  onContentChange={({ content }) => saveContent(content)}
>
  <Editor.View />
</Editor.Root>

Set contentFormat to choose the canonical type Cubitt receives and emits. Consumers do not need separate props for Markdown and BlockNote JSON.

BlockNote JSON

Use contentFormat="blocknote" when the consuming app can persist BlockNote blocks directly. This is the richest mode and supports the full free BlockNote editing surface, including toggle blocks, file/media blocks, tables, slash commands, drag handles, side menu, and table handles.

<Editor.Root
  content={blocks}
  contentFormat="blocknote"
  onContentChange={({ content }) => saveBlocks(content)}
  uploadFile={uploadFile}
>
  <Editor.View />
</Editor.Root>

In this mode, content is EditorPartialBlock[], and onContentChange emits EditorPartialBlock[].

Markdown

Use contentFormat="markdown" when the consuming app stores Markdown as the source of truth.

<Editor.Root
  content={markdown}
  contentFormat="markdown"
  onContentChange={({ content }) => saveMarkdown(content)}
>
  <Editor.View />
</Editor.Root>

In this mode, content is a string, and onContentChange emits a Markdown string.

Markdown mode intentionally narrows the editor UI to blocks and inline content that can round-trip through BlockNote's Markdown parser and exporter. It does not expose uploadFile or resolveFileUrl because dedicated BlockNote file and media blocks are not native Markdown content.

Supported Blocks

BlockNote mode supports the default free BlockNote block set:

BlockBlockNote JSONMarkdown
ParagraphYesYes
Heading 1-6YesYes
QuoteYesYes
Bullet listYesYes
Numbered listYesYes
ChecklistYesYes
Code blockYesYes
TableYesYes
DividerYesYes
ImageYesMarkdown image syntax
FileYesMarkdown link only
VideoYesMarkdown link only
AudioYesMarkdown link only
Toggle headingYesNo
Toggle list itemYesNo

Markdown can preserve file, video, and audio references as links, but those links are not the same as BlockNote's dedicated file/media blocks. If an app needs first-class uploads, previews, captions, and file panels, persist BlockNote JSON.

Controlled Content

Use content for controlled content. This is the right path for reactive data sources such as TanStack DB query results.

<Editor.Root
  content={markdown}
  contentFormat="markdown"
  onContentChange={({ content }) => setMarkdown(content)}
>
  <Editor.View />
</Editor.Root>

contentFormat determines the type for all content props and change events.

On this page