Skip to main content

draw.io for React

Add the draw.io diagram editor to your React app. One component, typed events and methods, and examples you can copy.

Free • No API key • TypeScript • Next.js

Diagram.tsx
import { DrawioEditor } from "@drawio/react";

type Props = { xml?: string; onSave: (xml: string) => void };

export default function Diagram({ xml, onSave }: Props)
{
return <DrawioEditor xml={xml} onSave={(event) => onSave(event.xml)} />;
}

Get started​

Install the package and add the editor to a component.

  1. Install the package:
npm install @drawio/react
  1. Add the editor to a component. It fills its container, so give the container a height:
QuickStart.tsx
import { useState } from "react";
import { DrawioEditor } from "@drawio/react";

// The editor loads `xml` and calls onSave when the user clicks Save.
export default function QuickStart()
{
const [xml, setXml] = useState<string>();

return (
<div style={{ height: 600 }}>
<DrawioEditor
xml={xml}
onSave={(event) => setXml(event.xml)}
// Light or dark like the system
urlParameters={{ dark: "auto" }}
/>
</div>
);
}

The draw.io editor will open in your app. When the user clicks Save, onSave receives the diagram as XML. Continue with the examples for autosave, exports and more.

Examples​

Each example is one file. Copy it into your app, or run all of them from the repository.

Stores every change, here in the browser's local storage. setModified(false) tells the editor that the change is stored, so it doesn't ask before the page is left.

Autosave.tsx
import { useRef, useState } from "react";
import { DrawioEditor, type DrawioEditorHandle } from "@drawio/react";

const KEY = "drawio-example";

// Saves every change in the browser's local storage. Reload the page: the
// diagram is still there. Replace localStorage with a call to your backend.
export default function Autosave()
{
const [xml] = useState(() => localStorage.getItem(KEY) ?? undefined);
const editor = useRef<DrawioEditorHandle>(null);

return (
<div style={{ height: 600 }}>
<DrawioEditor
ref={editor}
xml={xml}
autosave
onAutosave={(event) =>
{
localStorage.setItem(KEY, event.xml!);
// Stored: the editor does not ask before the page is left
editor.current!.setModified(false);
}}
// Light or dark like the system, without the Save, Save and Exit and Exit buttons
urlParameters={{ dark: "auto", noSaveBtn: true, saveAndExit: false, noExitBtn: true }}
/>
</div>
);
}

Run all examples on your computer:

git clone https://github.com/jgraph/drawio-react.git
cd drawio-react
npm install
npm run examples

What the component does

It runs the draw.io editor in an iframe in embed mode, and handles the messages between your app and the editor.

Running in minutes

One component with props for the diagram and callbacks for save, autosave and exit. The editor fills its container.

Typed protocol

Every action and event of embed mode has a TypeScript type. Methods such as export() and getXml() return promises, and wait for the editor to load.

Safe messages

Accepts messages only from its own iframe and the origin of the editor, and sends diagrams only there. Several editors on one page work independently.

Next.js and SSR

Marked as a client component. On the server, it renders the iframe without starting the editor, so no message is lost during hydration.

Self-hosted draw.io

Set baseUrl to load the editor from your own server, for example from the jgraph/drawio Docker image.

jgraph/drawio on Docker Hub →

GitHub repository

The source code, the examples to run, and the tests against the draw.io editor.

jgraph/drawio-react on GitHub →

Props and methods​

The most used ones. The types in the package describe all of them.

PropDescription
xmlThe diagram: draw.io XML, or a PNG or SVG data URI with a diagram inside. A new value loads it, unless it is the diagram the editor last sent.
descriptorMermaid, PlantUML or CSV to convert instead: {format: "mermaid", data}
autosaveCalls onAutosave after every change
templatesShows the template dialog when there is no xml
urlParametersLook of the editor, for example {ui: "min", dark: "auto", lang: "de", libraries: true}. A change reloads the editor with the current diagram. See the URL parameters.
configThe configuration: fonts, colours, styles and shape libraries
loadOptionsMore options for loading, for example title, dark, fit or exportProtocol. See the load action.
baseUrlURL of a self-hosted draw.io. The default is https://embed.diagrams.net/.
onLoad, onSave, onAutosave, onExit, onExportEvents of the editor
onEventEvery event, with its type: switch (event.event)
Method of the refDescription
getXml()Returns the diagram
export({format})Returns a PNG, SVG, editable SVG (xmlsvg), JSON or HTML export
load({xml}), merge(xml)Replaces the diagram, or merges changes into it
setModified(false)Marks the diagram as stored, for example after an autosave
fit(), viewbox(rect), layout(layouts)Changes the view, or arranges the diagram
prompt(), dialog(), status(), spinner()Shows a prompt, a message, a status or a spinner in the editor
invokeAction(name)Runs an action of the editor, for example undo, zoomIn or save

Privacy and security

  • Your app stores the diagrams. The editor sends them to your page, and draw.io doesn't store them.
  • Set baseUrl to a fixed address, never to user input: the editor at that address gets your diagrams.
  • The editor loads from embed.diagrams.net. To load it from your own server, run draw.io yourself and set baseUrl.
  • The component accepts messages only from its own iframe and the origin of the editor, and sends diagrams only to that origin.
  • Links in a diagram come from the diagram. Check the href of openLink events before your app opens them.

Questions and troubleshooting

The editor shows a 403 error

embed.diagrams.net serves pages on the standard ports of http and https, and on localhost on any port. A page on another port, a headless browser and some sites get a 403 error in the frame. For those, run draw.io yourself, for example with the jgraph/drawio Docker image, and set baseUrl to its address, here http://localhost:8080/:

docker run -it --rm -p 8080:8080 jgraph/drawio
The editor shows the spinner and doesn't load the diagram

Check the console of your browser. If the URL of the editor redirects, for example from http to https, the component ignores the messages of the new address and logs a warning. Use the final URL as baseUrl.

If your app has a Content Security Policy, allow the editor in a frame:

frame-src https://embed.diagrams.net
How do I store diagrams in my backend?

Send the XML of onSave or onAutosave to your server. After an autosave is stored, call setModified(false):

<DrawioEditor
ref={editor}
xml={xml}
autosave
onAutosave={async (event) =>
{
await fetch("/api/diagrams/1", { method: "PUT", body: event.xml });
editor.current!.setModified(false);
}}
/>
How do I show a diagram without the editor?

Store it as an SVG image with the diagram inside, with export({format: "xmlsvg"}), and show it with an img element. The editor opens the image again. See the editable image example.

Which files can the editor open?

The xml prop accepts draw.io XML, PNG and SVG files with a diagram inside as data URIs, Visio files as data URIs, and Lucidchart and Gliffy JSON. The descriptor prop converts Mermaid, PlantUML and CSV.

Can I hide buttons and menus?

Yes. urlParameters={{noSaveBtn: true, saveAndExit: false, noExitBtn: true}} hides the Save, Save and Exit and Exit buttons. The hideMenuItems option of the configuration hides menu items.

How do I use dark mode?

Set urlParameters={{dark: "auto"}}, and the editor follows the light or dark mode of the system. Use true or false to set it. With "auto", the SVG images of export({format: "xmlsvg"}) also show the diagram in the light or dark mode of the page.

Can I put several editors on one page?

Yes. Each editor accepts only the messages of its own iframe.

Do I need an API key or an account?

No. The component and the editor are free to use, and the editor needs no sign-in.

Learn more

The embed mode reference describes every message between your app and the editor, and the configuration reference every option of the editor.