Quick start
import { Diagrams } from '@tiptap-pro/extension-diagrams'
import { bpmnDiagramRenderer } from '@tiptap-pro/extension-diagrams/bpmn'
import rendererUrl from '@tiptap-pro/extension-diagrams/bpmn-renderer?url&no-inline'
import viewerUrl from 'bpmn-js/dist/bpmn-viewer.production.min.js?url&no-inline'
Diagrams.configure({
diagramRenderers: [bpmnDiagramRenderer({ viewerUrl, rendererUrl })],
})
editor.commands.insertFlowDiagram({ source: bpmnXml, format: 'bpmn', title: 'Payment check' })bpmn-js is not a dependency of the package. Install it yourself, serve its bundles as files, and accept its own license.
Options
| Option | Type | Description |
|---|---|---|
viewerUrl | string | Required. A bpmn-js bundle: bpmn-js/dist/bpmn-viewer.production.min.js. The modeler bundle works too |
rendererUrl | string | Required. @tiptap-pro/extension-diagrams/bpmn-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 'bpmn' |
label | string | Default 'BPMN' |
How it draws
bpmn-js runs in one iframe per page, with sandbox="allow-scripts" and a policy that allows no
network request. The iframe is laid out off screen, because bpmn-js measures labels while it
draws. It loads for the first BPMN diagram, and each drawing is cached by source.
- Layout. The XML must carry its layout (BPMN DI), as a modeler saves it. A process without a layout does not draw.
- Colors. A diagram is drawn black on white, on a page of its own. The
--tt-flow-diagram-*custom properties do not reach it. - PNG, WebP, JPEG and Word exports. Labels are SVG text, so the file looks like the diagram in the editor.
- On a server. A BPMN diagram cannot be exported, because bpmn-js lays out text in a browser.
The bpmn.io attribution
The Renderer's rules ask for a "Powered by bpmn.io" link with the bpmn.io logo. It is shown below
the diagram and drawn into every exported file. rendererRules cannot remove it. See
Rules of your Renderer.
What a BPMN source is
- The root element is
definitionsin the namespacehttp://www.omg.org/spec/BPMN/20100524/MODEL, under any prefix. The root element declares the namespace. - The XML ends with the closing tag of that root element, such as
</bpmn:definitions>. - The document stores it as written, layout included. Only a byte-order mark and the white space around the XML are removed.
- Empty source is allowed, for a process you have not modeled yet.
- Pasting BPMN XML as text gives a BPMN diagram.
detectDiagramInputreturns{ kind: 'bpmn' }for it.
insertFlowDiagram and updateFlowDiagram return false for anything else, and for source
longer than 1,000,000 characters.
Editing in the modeler
connectBpmnEditor runs the bpmn-js modeler in an iframe you created, sandboxed with scripts
only, and opens a diagram in it. You build the dialog, the iframe and the buttons. The package
gives you the XML when you ask for it.
import { connectBpmnEditor } from '@tiptap-pro/extension-diagrams/bpmn'
import rendererUrl from '@tiptap-pro/extension-diagrams/bpmn-renderer?url&no-inline'
import fontUrl from 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css?url&no-inline'
import bpmnStyleUrl from 'bpmn-js/dist/assets/bpmn-js.css?url&no-inline'
import diagramStyleUrl from 'bpmn-js/dist/assets/diagram-js.css?url&no-inline'
import modelerUrl from 'bpmn-js/dist/bpmn-modeler.production.min.js?url&no-inline'
const frame = document.createElement('iframe')
dialog.append(frame)
const connection = connectBpmnEditor(frame, {
modelerUrl,
rendererUrl,
styleUrls: [diagramStyleUrl, bpmnStyleUrl, fontUrl],
source: diagram.source,
onReady: () => (saveButton.disabled = false),
})
saveButton.onclick = async () => {
const source = await connection.save()
editor.commands.updateFlowDiagram({ pos, source, format: 'bpmn' })
connection.destroy()
dialog.close()
}connectBpmnEditor(frame, options)
| Option | Type | Description |
|---|---|---|
modelerUrl | string | Required. The bpmn-js modeler bundle, bpmn-js/dist/bpmn-modeler.production.min.js |
rendererUrl | string | Required. @tiptap-pro/extension-diagrams/bpmn-renderer, the same file the Renderer uses |
styleUrls | readonly string[] | Required. The modeler's stylesheets: diagram-js.css, bpmn-js.css and bpmn-font/css/bpmn-embedded.css |
scriptNonce | string | null | For pages with a nonce-based Content Security Policy |
source | string | The BPMN XML to open. Empty opens a new process with a start event |
onReady() | () => void | Called when the diagram is open and can be edited |
onChange() | () => void | Called after every change in the modeler |
onError(message) | (message) => void | Called when the modeler did not load, or could not open the source |
It returns { save, destroy }:
| Function | Returns |
|---|---|
save() | A Promise of the diagram as it is now, as BPMN XML. It rejects when the modeler sends something that is not BPMN |
destroy() | Nothing. Stops listening and empties the iframe. The iframe stays yours |
Use the embedded font stylesheet, because the modeler's fonts must come from a data: URL or
from the origin of a stylesheet.
The modeler works on a copy. If others change the same diagram while it is open, the next save replaces their changes.