Mermaid-compatible text is the human-readable body of a diagram; a Grafloria sidecar carries the document data that Mermaid cannot express, so text and the live canvas can reconcile in both directions.
How the parts fit together
mermaidflowchart LR S["Mermaid-compatible body"] --> I["importDiagramText()"] C["Grafloria sidecar"] --> I I --> M["DiagramModel"] M --> R["render()"] R --> D["live DiagramInstance"] D --> E["exportText() / exportDiagramText()"] E --> S E --> C
The body contains structure and labels that other Mermaid renderers can read. The %%grafloria:document comment contains the serialized document, and %%grafloria:body-hash records which body produced it. Mermaid ignores both comments.
With the default lossless export, importing an unchanged file uses the sidecar. Positions, sizes, styles, ports, groups, and viewport data therefore survive the round trip. Transient selection state and derived link routing are not committed to the sidecar.
Import Mermaid text
Use importDiagramText when text is the input. It returns a DiagramModel, the source that produced it, and flags that describe reconciliation.
tsimport { importDiagramText } from '@grafloria/engine';
const sourceText = `flowchart
start[Start] --> finish[Finish]`;
const result = importDiagramText(sourceText);
if (result.unsupported) {
console.error(`Unsupported Mermaid type: ${result.unsupported}`);
} else {
console.log(result.source);
console.log(result.diagram.getNodes().length);
}
Pure Mermaid text takes the DSL path. It is best effort because Mermaid syntax does not contain every model property. Imported nodes still become typed model nodes, so the rendered diagram uses the diagram type's semantics.
Do not guess an unsupported type or render it as another type. Inspect result.unsupported; Grafloria reports the recognised but unsupported diagram type and returns an empty diagram rather than a plausible wrong graph.
Export a diagram for humans and machines
Use exportDiagramText with a model when you need a text file outside a mounted renderer. The DiagramSerializer in this example compares the document before and after the text round trip. The default is lossless:
tsimport { DiagramSerializer, exportDiagramText, importDiagramText } from '@grafloria/engine';
import { render } from '@grafloria/element';
const host = document.createElement('div');
host.style.height = '400px';
document.body.append(host);
const instance = render({
nodes: [
{ id: 'plan', position: { x: 60, y: 90 }, size: { width: 150, height: 66 }, data: { label: 'Plan' } },
{ id: 'ship', position: { x: 320, y: 90 }, size: { width: 150, height: 66 }, data: { label: 'Ship' } },
],
edges: [{ id: 'plan-to-ship', source: 'plan', target: 'ship' }],
}, host);
const before = new DiagramSerializer().serialize(instance.getModel());
const text = exportDiagramText(instance.getModel());
const imported = importDiagramText(text);
const after = new DiagramSerializer().serialize(imported.diagram);
console.assert(imported.source === 'sidecar');
console.assert(JSON.stringify(before) === JSON.stringify(after));
The returned text remains valid Mermaid for external viewers. Pass { lossless: false } when you need only the portable Mermaid body; that crosses the lossy boundary, so Grafloria-specific geometry and styling are not preserved by a later pure-text import. Pass { positions: true } when exact positions should also be written as readable Grafloria directives in the body; the sidecar remains the lossless source.
Reconcile text with a mounted instance
The render function mounts a real canvas and returns a DiagramInstance. Use the instance's exportText() and loadText() methods when an editor has both a text area and a canvas. loadText() reconciles into the existing diagram, so listeners, plugins, and selection remain attached.
tsimport { render } from '@grafloria/element';
const host = document.createElement('div');
host.style.height = '400px';
const editor = document.createElement('textarea');
editor.style.width = '100%';
editor.style.height = '180px';
document.body.append(host, editor);
const instance = render({
nodes: [
{ id: 'plan', position: { x: 60, y: 90 }, size: { width: 150, height: 66 }, data: { label: 'Plan' } },
{ id: 'build', position: { x: 300, y: 90 }, size: { width: 150, height: 66 }, data: { label: 'Build' } },
],
edges: [{ id: 'plan-to-build', source: 'plan', target: 'build' }],
}, host);
editor.value = instance.exportText();
editor.addEventListener('change', () => {
const result = instance.loadText(editor.value);
if (result.unsupported) {
console.error(`Unsupported Mermaid type: ${result.unsupported}`);
}
});
When the body is unchanged, the sidecar wins. When the body hash differs, auto treats the body as a human edit and applies its structure, labels, and shapes. If a sidecar exists, the edit is merged over the sidecar: geometry, styles, ports, groups, and viewport data that the body cannot express stay intact. The result reports bodyEdited: true, source: 'text', and sidecarMerged: true.
Choose the source explicitly with ImportTextOptions: prefer: 'sidecar' ignores body edits, while prefer: 'text' ignores the sidecar. The default prefer: 'auto' uses the body hash to choose. A malformed sidecar does not discard the body; sidecarInvalid reports the problem and the text path remains available.
Choose the representation
| Need | Use | Result |
|---|---|---|
| Save and restore the full document | DiagramSerializer or the lossless text form | Model data survives through the document representation. |
| Give a person or Mermaid renderer readable text | exportDiagramText(model, { lossless: false }) | Pure Mermaid-compatible body; Grafloria-only data is lossy. |
| Keep a text editor and canvas synchronized | instance.exportText() and instance.loadText(text) | Text changes reconcile into the mounted instance. |
| Detect an unsupported Mermaid type | importDiagramText(text).unsupported | The type name is explicit; no wrong diagram is guessed. |
For a mounted editor, start at the instance. Use the model-level functions when importing before mounting, exporting a model for storage, or processing text without a renderer.
See it running
Open the live Mermaid round-trip demo. It shows the Mermaid body beside the canvas: leave the sidecar unchanged to restore the exact document, or edit the body to see the text reconciliation path.
Related: Edit Mermaid diagrams, Model and documents, and Export diagrams.
Was this page helpful?