Quick start
import { Diagrams } from '@tiptap-pro/extension-diagrams'
import { drawioDiagramRenderer } from '@tiptap-pro/extension-diagrams/drawio'
import rendererUrl from '@tiptap-pro/extension-diagrams/drawio-renderer?url&no-inline'
import viewerUrl from './vendor/drawio/viewer-static.min.js?url'
Diagrams.configure({
diagramRenderers: [drawioDiagramRenderer({ viewerUrl, rendererUrl })],
})Options
| Option | Type | Description |
|---|---|---|
viewerUrl | string | Required. The draw.io viewer, viewer-static.min.js from a draw.io release (src/main/webapp/js/ in the jgraph/drawio repository). It is not on npm, so serve it yourself |
rendererUrl | string | Required. @tiptap-pro/extension-diagrams/drawio-renderer, served as a file. With Vite, ?url&no-inline |
scriptNonce | string | null | For pages with a nonce-based Content Security Policy |
id | string | Default 'drawio' |
label | string | Default 'draw.io' |
What a draw.io source is
A diagram with format: 'drawio' holds draw.io XML:
editor.commands.insertFlowDiagram({ source: drawioXml, format: 'drawio', title: 'Order process' })- The source is an
<mxfile>or a bare<mxGraphModel>. - The document stores an
<mxfile>whose pages are plain XML, so you can read and compare the stored text. - A bare model becomes a file with one page.
- A page that draw.io compressed is uncompressed. A page that cannot be uncompressed is kept as it is.
- Pasting draw.io XML as text gives a draw.io diagram.
insertFlowDiagram and updateFlowDiagram return false for anything else, and for source
longer than 1,000,000 characters.
updateFlowDiagram({ source, format }) changes a diagram's format, for example when a Mermaid
diagram comes back from the draw.io editor. A new format needs a new source in the same call.
How it draws
The draw.io viewer runs in one hidden iframe per page, with sandbox="allow-scripts" and a
policy that allows no network request. It loads the first time a draw.io diagram is drawn, and
is about 4.4 MB, or 940 kB compressed. Drawing takes tens of milliseconds, and the result is
cached by source.
What the diagram looks like
- Colors. A diagram keeps the colors it was drawn with. The
--tt-flow-diagram-*custom properties do not reach it. - Background. A diagram is drawn on its own background, or on white.
- Color scheme. The SVG follows the page's light or dark color scheme where draw.io supports it.
- HTML labels are drawn.
- Links in labels do nothing, because the diagram is shown as an image.
- Stencil shapes from AWS, Azure, Cisco and other libraries draw as empty boxes. The viewer cannot load their files in the sandbox.
- Images in a diagram must be
data:URLs.
In an export
- PNG, WebP, JPEG and Word. Labels are plain text. Bold, colors and line breaks written as HTML inside a label are lost.
- On a server. A draw.io diagram cannot be exported, because the viewer lays out text in a browser.
Editing in the draw.io editor
The entry point connects the draw.io editor in its JSON embed mode. You build the dialog and the iframe, and the package gives you what the editor saves.
import { connectDrawioEditor, drawioEditorUrl } from '@tiptap-pro/extension-diagrams/drawio'
const frame = document.createElement('iframe')
frame.src = drawioEditorUrl() // https://embed.diagrams.net/?embed=1&proto=json…
dialog.append(frame)
const connection = connectDrawioEditor(frame, {
source: diagram.source,
title: diagram.title ?? undefined,
onSave: (source) => editor.commands.updateFlowDiagram({ pos, source, format: 'drawio' }),
onExit: () => {
connection.destroy()
dialog.close()
},
})drawioEditorUrl(options?)
Builds the editor URL.
| Option | Type | Description |
|---|---|---|
base | string | The draw.io editor. Default https://embed.diagrams.net/. Point it at your own copy to keep diagrams off a third-party origin |
saveAndExit | boolean | Offers Save and Exit next to Save. Default true |
params | Record<string, string> | Adds editor URL parameters, such as lang |
connectDrawioEditor(frame, options)
Opens a diagram in the editor in frame. Returns { destroy }.
| Option | Type | Description |
|---|---|---|
source | string | The draw.io XML to open. Empty opens a blank page |
mermaid | string | Mermaid source to open instead. The editor converts it to draw.io shapes, and a subgraph to a swimlane |
title | string | Shown in the editor's title bar |
onSave(source, { exit }) | (source, { exit }) => void | Required. Called with the XML on Save, and with exit: true on Save and Exit |
onExit() | () => void | Required. Called when the editor closes, also after Save and Exit |
onAutosave(source) | (source) => void | When set, called with the XML after every change |
onError(message) | (message) => void | Called when the editor could not open the source, or sent something that is not draw.io XML |
- The diagram is posted only to the origin of the iframe's URL.
- Messages are read only from that iframe and origin.
- What
onSavereceives is normalized like any stored draw.io source. See What a draw.io source is. - The editor works on a copy. If others change the same diagram while it is open, the next save replaces their changes.
From Mermaid to draw.io
Open a Mermaid diagram with the mermaid option and save it with format: 'drawio'. It becomes
a draw.io diagram. You can go back to Mermaid only with undo.
Hosting the editor yourself
The draw.io editor is a static web app, published as the jgraph/drawio Docker image:
docker run --rm -p 8080:8080 jgraph/drawioframe.src = drawioEditorUrl({ base: 'http://localhost:8080/' })- The diagram is posted only to that origin, so nothing reaches draw.io's servers.
- Serve it over HTTPS if your page is served over HTTPS.
- Nothing else changes. The embed protocol is the same as on
embed.diagrams.net. - Editing then works without an internet connection. Web fonts in labels and online shape libraries still need the network.
- Pin the image to a tag. Update it together with the viewer you serve as
viewerUrl, so the editor and the viewer read the same XML.