BlockNote DocsFeaturesBuilt-in BlocksDiagrams

Diagrams

The @blocknote/diagram-block package adds a diagram block: authored as Mermaid source in a source popup and rendered by Pele. Diagram renderers load on demand, supporting flowcharts, sequence diagrams, Gantt charts, and other supported diagram types.

This block is only available in React (@blocknote/react).

npm install @blocknote/diagram-block

Adding to your editor

The package exports createReactDiagramBlockSpec. Add it to your schema's blockSpecs:

import { BlockNoteSchema } from "@blocknote/core";
import { createReactDiagramBlockSpec } from "@blocknote/diagram-block";

const schema = BlockNoteSchema.create().extend({
  blockSpecs: {
    // Adds the Diagram block to the schema.
    diagram: createReactDiagramBlockSpec(),
  },
});

To highlight the Mermaid source in the popup, add the syntax highlighting extension to your editor. The diagram block already declares its source language (mermaid), so no per-block configuration is needed:

import { syntaxHighlighter } from "@blocknote/code-block";

const editor = useCreateBlockNote({
  schema,
  extensions: [syntaxHighlighter],
});

Because the diagram spec lives in an optional package, its editor integrations are opt-in too — the package exports everything needed:

import {
  getDiagramSlashMenuItems, // Slash Menu item for inserting a diagram
  getDiagramBlockTypeSelectItems, // Block Type Select item for the Formatting Toolbar
  locales as diagramLocales, // dictionary strings, merged under the `diagram` key
} from "@blocknote/diagram-block";
  • getDiagramSlashMenuItems(editor) returns a Slash Menu item for inserting a diagram — combine it with the default items via combineByGroup.
  • getDiagramBlockTypeSelectItems(editor) returns a Block Type Select item for turning a block into a diagram, to spread alongside the defaults.
  • diagramLocales translates the diagram strings — merge a locale into the editor's dictionary under the diagram key (see Localization); without one, the bundled English strings are used.

The example below wires them all up.

Example

Renderer compatibility

Stored diagrams and Markdown fences still use Mermaid source, so existing documents need no migration. Pele has its own layout and visual style. Mermaid themes and themeVariables do not apply; use Pele's CSS variables to customize previews. Arbitrary HTML labels and external Mermaid plugins such as ZenUML are not supported.

The renderer switch removes the exported Mermaid-specific helpers initializeMermaid, defaultMermaidOptions, trimDiagramSVG, setSVGFontFamily, and withSVGFontFamily. If you used these helpers directly, replace rendering with renderDiagram, or use renderDiagramToSVG / renderDiagramToImage for export images. Pass the font family to the renderer instead of rewriting the resulting SVG. Global initialization and DOM-based trimming are no longer needed.

Theming

Diagram previews automatically inherit your editor's theme, including live light/dark changes. No diagram-specific configuration is needed:

  • Mantine: uses BlockNote's colors and corner radius, including values from a custom theme object.
  • Ariakit / React: uses the shared --bn-* theme variables.
  • Shadcn: uses the host's semantic color variables (--background, --foreground, --muted, --border, --primary, and --destructive), --radius, and --chart-1 through --chart-5. These must contain complete CSS colors, as in Shadcn's current themes. Missing variables fall back to BlockNote's palette. Dark mode follows the host's token changes, typically through its .dark class.

Chart series use BlockNote's highlight colors, or Shadcn's chart tokens when available. To override individual diagram colors without changing the rest of the editor, set Pele variables on your editor container or a diagram:

.bn-root {
  --pele-accent: #6366f1;
  --pele-radius: 8px;
}

Explicit colors authored in Mermaid style / classDef rules take precedence over theme defaults. Editor theme variables affect previews only; exported images use the standalone renderer's defaults. Use a custom renderDiagram export callback to supply a different export palette.

Exporting

Diagrams export to every format BlockNote supports. Markdown works out of the box — diagrams export as ```mermaid fenced code blocks, their common Markdown notation.

The PDF (and Typst), DOCX, ODT, and email exporters embed the diagram as an image via their mappings — they live as subpaths of this package, and each exports a createDiagramBlockMapping factory to spread into the exporter's default mappings. The DOCX exporter shown here; the others work the same way with their respective subpaths:

import {
  DOCXExporter,
  docxDefaultSchemaMappings,
} from "@blocknote/xl-docx-exporter";
import { createDiagramBlockMapping } from "@blocknote/diagram-block/docx-exporter";
// ...or "@blocknote/diagram-block/typst-exporter" (PDF + Typst - embeds
//       vector SVG with labels as real text),
//       "@blocknote/diagram-block/odt-exporter",
//       "@blocknote/diagram-block/email-exporter"

const exporter = new DOCXExporter(editor.schema, {
  ...docxDefaultSchemaMappings,
  blockMapping: {
    ...docxDefaultSchemaMappings.blockMapping,
    diagram: createDiagramBlockMapping(),
  },
});

The factory takes one option:

createDiagramBlockMapping(options?: {
  /**
   * Renders the Mermaid source to an image. Defaults to Pele, producing
   * PNG for DOCX, ODT, and email, or vector SVG for Typst / PDF.
   */
  renderDiagram?: RenderDiagram;
});

Invalid Mermaid sources render an error placeholder identifying the offending source, mirroring the editor.

The email subpath's factory additionally takes an imageDelivery option: some email clients don't display the default data URL images, and the generated images can be delivered as inline cid: attachments instead — see image delivery on the email page.

Exporting server-side

Typst / PDF exports work on the server out of the box: Pele produces vector SVG without a browser. Labels use the exporter's font family; make those fonts available to the PDF compiler. Exports resolve Pele's default colors so standalone SVG consumers do not need CSS variables; preview-only CSS overrides are not included.

DOCX, ODT, and email use PNG images. Their built-in rasterizer requires browser canvas. For server-side exports to those formats, pass a renderDiagram function to createDiagramBlockMapping; without one, the export throws:

import { createDiagramBlockMapping } from "@blocknote/diagram-block/docx-exporter";
import type { RenderDiagram } from "@blocknote/diagram-block/docx-exporter";

const renderDiagram: RenderDiagram = async (source) => {
  // Render the Mermaid source to an image with your renderer of choice.
  return {
    image: { data: pngBytes, mimeType: "image/png", width, height },
  };
};

createDiagramBlockMapping({ renderDiagram });

For example, render SVG using Pele's renderAsync from pele/lazy and rasterize it with a server-side SVG-to-PNG tool. Invalid Mermaid source is an expected failure: return it as { error } rather than throwing, and the export renders the error placeholder for that block instead of failing.