Skip to content

Configuration

David Benson edited this page Oct 7, 2026 · 1 revision

This page explains how a draw.io instance is configured: URL parameters, global variables, the Editor.configure JSON and the preferences stored in the browser, and which one wins when they disagree. It is for developers who host, embed or customise the editor. The complete user-facing references are Supported URL parameters and Configure the draw.io editor; this page explains the mechanics behind them.

The layers at a glance

Layer Set in Read by Scope
URL parameters The page URL, a #P... hash, or urlParams[...] in PreConfig.js bootstrap.js, Init.js and code throughout One page load
Global variables js/PreConfig.js, js/PostConfig.js, or the page that embeds draw.io Init.js and the code that uses them The deployment
Editor.configure window.DRAWIO_CONFIG, Extras > Configuration (stored in localStorage), or the configure=1 message in embed mode App.main, before the UI is created The deployment, one browser, or one embedding
Preferences The UI (language, theme, libraries, units, ...) mxSettings in js/diagramly/Settings.js One browser

All four are read once at startup. Changing any of them requires a reload.

Precedence

The rules that decide between the layers, as implemented:

Setting Order, strongest first
Any URL parameter A value assigned in PreConfig.js, then the page URL. PreConfig.js runs after bootstrap.js has parsed the URL, so urlParams['x'] = ... replaces what the user passed. Write if (urlParams['x'] == null) urlParams['x'] = ...; for a default that the URL can still override
Grid and page view of a diagram The grid and pv URL parameters, then the grid and page attributes of the file's <mxGraphModel>, then the defaults. This holds on load and when switching pages, and the file's own values are written back unchanged when it is saved
Connectable, connection arrows, folding defaultConnectable, defaultConnectionArrowsEnabled and defaultFoldingEnabled in the configuration, then the file's connect, arrows and fold attributes (again written back unchanged on save)
Configuration In embed mode with configure=1, only the configuration in the configure message. Otherwise DRAWIO_CONFIG is applied first and the local configuration from Extras > Configuration second (not in embed mode), so where both set a key the local value wins
Stored preferences against the configuration The stored preferences, unless the configuration's version differs from the version they were saved with, or the configuration sets override: true. Then they are discarded and rebuilt from the configured defaults
UI language window.mxLanguage set in PreConfig.js, then the lang URL parameter, then the language saved in the preferences, then (on app.diagrams.net and a few other draw.io hosts only) the browser language, then English
Theme window.uiTheme set in PreConfig.js, then the ui URL parameter, then the theme saved in the preferences, then the classic theme

The language rule matters for self-hosters: on your own host the browser language is not used, and setting mxLanguage unconditionally in PreConfig.js overrides both the URL and the user's choice. To set only a default, check first:

try
{
	if (urlParams['lang'] == null)
	{
		var saved = (isLocalStorage) ? localStorage.getItem('.drawio-config') : null;

		if (saved == null || !JSON.parse(saved).language)
		{
			window.mxLanguage = 'de';
		}
	}
}
catch (e)
{
	// ignore unreadable preferences
}

URL parameters

bootstrap.js splits window.location.search into the global urlParams object. Values are stored as they appear in the URL, without decoding; code that expects encoded values decodes them itself. A hash of the form #P followed by URL-encoded JSON is parsed as well (it lets a CDN cache one URL for many parameter sets); query string parameters fill in any keys the JSON does not set.

js/diagramly/Init.js then derives further values, so a parameter can imply others:

  • lightbox=1 sets chrome=0.
  • embedInline=1 sets embed=1, ui=sketch, plugins=0, proto=json, prefetchFonts=1, and pv=0 unless given.
  • ui=dark sets dark=1.
  • offline=1, demo=1, stealth=1, local=1 and lockdown=1 set gapi, db, od, gh, gl, tr, ms365 and picker to 0 (gapi-stealth=1 keeps Google Drive).
  • splash is set to 0 unless the URL gives it or the configuration sets showSplashOnStart: true.
  • lockdown is also taken from a lockdown key in the local configuration.
  • mode=trello sets tr=1; gitlab and gitlab-id set DRAWIO_GITLAB_URL and DRAWIO_GITLAB_ID.

The parameters developers most often need:

Parameter Effect
dev=1 Development mode: loads the sources instead of the bundles (Getting started)
test=1 Turns on EditorUi.debug console output, including configuration errors
embed=1, proto=json, configure=1 Embed mode, the JSON message protocol, and waiting for a configuration message, see Embedding
chrome=0, lightbox=1 Read-only viewer, and the lightbox variant of it
ui=kennedy, simple, min, sketch, atlas; dark=0, 1, auto Theme and dark mode
lang=xx UI language (codes as in mxLanguageMap in Init.js)
p=id1;id2 Loads built-in plugins by their IDs in App.pluginRegistry, see Plugins
plugins=0 Loads no plugins
mode=device, browser, google, onedrive, github, gitlab, ... Storage to start with
gapi=0, od=0, ms365=0, gh=0, gl=0 Disable Google Drive, OneDrive, Microsoft 365, GitHub and GitLab. Dropbox and Trello are off unless db=1 and tr=1
browser=0 or 1, noDevice=1 Hide browser storage or offer it at startup; hide device storage
offline=1 Disables cloud storage and plugins, and allows the service worker on any host (see Self-hosting for its limits)
local=1 Device storage only; localStorage is not used at all
stealth=1, lockdown=1 No features that use external services; lockdown also stops all transmission except to the chosen storage (data governance lockdown)
sync=auto, manual, none Real-time collaboration mode (DrawioFile.SYNC). This repository's PreConfig.js forces manual
splash=1 Show the start screen even though Init.js defaults it off
grid=0 or 1, pv=0 or 1 Grid and page view, overriding the file
math=0 No MathJax
pwa=0, enableSW=1 Never use the service worker; use it on any host
print-csp=1 With dev=1, prints draw.io's Content-Security-Policies to the console

Some values are deliberately not accepted from the URL. For example, the export service can only be set with window.EXPORT_URL, because a link that chose the service could send the diagram to whoever wrote the link (GHSA-ff67-v9r9-6877).

Global variables

Global variables configure where the instance and its services live (DRAWIO_BASE_URL, DRAWIO_LIGHTBOX_URL, EXPORT_URL, PROXY_URL, ...), resource paths, plugins and the storage integrations. They are set in js/PreConfig.js before Init.js applies defaults, or cleared in js/PostConfig.js after it. The full list with defaults is in Self-hosting, and the two hook files are described in Self-hosting.

One rule to remember: most defaults are applied with window.X = window.X || default, so a null set in PreConfig.js is replaced by the default. Clear such variables in PostConfig.js.

Editor.configure

Editor.configure(config) in js/diagramly/Editor.js takes a plain JSON object and applies each known key, mostly by setting static fields and prototype defaults (Menus.prototype.defaultFonts, Graph.prototype.defaultVertexStyle, Sidebar.prototype.defaultEntries and so on). App.main calls it before it creates the UI and then loads the stored preferences again, which is why the configuration can define defaults for both. The object is kept in Editor.config; unknown keys are ignored, and keys with the wrong type are skipped with a "Configuration Error" message that only appears with test=1 (or debug: true in the configuration).

Where the configuration comes from

window.DRAWIO_CONFIG. Set it in PreConfig.js for everyone using the instance. With Docker, use the DRAWIO_CONFIG or DRAWIO_CONFIG_FILE environment variables (Self-hosting).

Extras > Configuration. The configuration dialog (js/diagramly/ConfigEditor.js for the visual editor) stores the JSON in localStorage under .configuration (Editor.configurationKey) when you click Apply, for the current browser only. It is not offered in embed mode. Its buttons:

  • Reset removes the stored configuration.
  • Preferences shows the stored preferences (.drawio-config) as JSON and can reset them.
  • Link creates a URL ending in #_CONFIG_ followed by the compressed JSON. Opening it asks the user twice before storing the configuration and reloading. A link whose JSON has the form {"merge": {...}} adds its keys to the existing local configuration instead of replacing it.

The configure=1 handshake in embed mode. With configure=1 in the URL, the editor ignores DRAWIO_CONFIG and the local configuration. It posts {"event":"configure"} (as a JSON string) to window.opener or window.parent and waits; nothing else starts until the host answers with a configure action:

var origin = 'https://embed.diagrams.net';
var iframe = document.createElement('iframe');

window.addEventListener('message', function(evt)
{
	if (evt.source == iframe.contentWindow && typeof evt.data === 'string')
	{
		var msg = JSON.parse(evt.data);

		if (msg.event == 'configure')
		{
			iframe.contentWindow.postMessage(JSON.stringify({action: 'configure',
				config: {defaultFonts: ['Humor Sans', 'Helvetica', 'Times New Roman']}}), origin);
		}
	}
});

iframe.setAttribute('src', origin + '/?embed=1&proto=json&configure=1');
document.body.appendChild(iframe);

The message must come from the opener or parent window, and its data must be a JSON string. Besides config, the message may carry colorSchemeMeta: true, which adds a color-scheme meta tag so that a transparent iframe follows the host's dark mode. The rest of the embed protocol is in Embedding and Embed mode.

Useful keys

All keys below are read by Editor.configure; the reference documents their values.

Area Keys
Fonts defaultFonts (replaces the font list; entries are names or {"fontFamily": ..., "fontUrl": ...}), customFonts (prepended), fontCss (@font-face rules), embedSvgFonts, enableLocalFonts (desktop)
Colours presetColors, customPresetColors, defaultColors, colorNames, defaultColorSchemes, customColorSchemes, defaultAdaptiveColors, enableLightDarkColors, darkColor, defaultPageBackgroundColor, defaultDarkPageBackgroundColor, defaultGridColor, defaultDarkGridColor
Styles defaultVertexStyle, defaultEdgeStyle (objects of style keys, see Styles), defaultTextStyle, styles, shadowColor, shadowOpacity, shadowOffsetX, shadowOffsetY, shadowBlur
Shape libraries defaultLibraries (semicolon-separated keys, for example "general;uml;er"), enabledLibraries (array; limits the built-in libraries offered in More Shapes and in shape search), libraries (custom sidebar entries), defaultCustomLibraries, enableCustomLibraries, expandLibraries, appendCustomLibraries, sidebarWidth, sidebarTitles, sidebarTitleSize, thumbWidth, thumbHeight, shapePicker
Templates and new files templateFile, enabledTemplateSections, customTemplates, emptyDiagramXml, emptyLibraryXml, defaultFileType
Canvas defaultPageVisible, defaultGridEnabled, defaultGridSize, gridSteps, pageFormat, defaultEdgeLength, zoomFactor, zoomWheel, defaultConnectable, defaultConnectionArrowsEnabled, defaultFoldingEnabled, copyOnConnect, stopEditingOnEnter, pasteAtMousePointer
User interface css and customCss (CSS injected into the page), hideMenus (top-level menu names such as "arrange"), hideMenuItems (action names), keyboardShortcuts, resources (override UI strings, optionally per language), compact, noAutoFocus, enableInlineToolbar, enableAnimations
Files and export compressXml, compressStyles, includeDiagram, autosaveDelay, restrictExport, removeImageMetadata, maxImageBytes, maxImageSize, enableExportUrl
Content globalVars (values for placeholders), simpleLabels, mermaid (default Mermaid configuration)
Embedding passiveScroll, noResizers, preserveViewState, passThroughKeys, suppressNewWindows, useInternalClipboard, see Embedding
AI diagram generation enableAi, aiModels, aiConfigs, aiActions, aiGlobals and the per-provider API key settings, see Configure AI options. enableAi is only on by default on app.diagrams.net
Storage of the configuration itself version, settingsName, debug

Three keys are read outside Editor.configure: override (in Settings.js, see Precedence), and showSplashOnStart and lockdown, which Init.js reads before any code runs (showSplashOnStart from DRAWIO_CONFIG or the local configuration, lockdown from the local configuration only).

Everything in DRAWIO_CONFIG is served to every browser that opens the instance. Anything you put there, including AI API keys, is readable by all users.

Worked example

To give everyone on an instance a corporate font, a short colour palette, blue default shapes, rounded orthogonal connectors and a small set of libraries, set DRAWIO_CONFIG in src/main/webapp/js/PreConfig.js:

window.DRAWIO_CONFIG = {
  "version": "2026-10",
  "defaultFonts": ["Helvetica", "Verdana",
    {"fontFamily": "Inter", "fontUrl": "https://fonts.googleapis.com/css?family=Inter"}],
  "presetColors": ["DAE8FC", "D5E8D4", "FFF2CC", "F8CECC", "E1D5E7"],
  "defaultVertexStyle": {"fillColor": "#DAE8FC", "strokeColor": "#6C8EBF", "fontFamily": "Inter"},
  "defaultEdgeStyle": {"edgeStyle": "orthogonalEdgeStyle", "rounded": "1",
    "jettySize": "auto", "orthogonalLoop": "1", "strokeColor": "#6C8EBF"},
  "defaultLibraries": "general;flowchart;uml",
  "enabledLibraries": ["general", "flowchart", "uml", "er", "bpmn"],
  "defaultGridEnabled": false
};

What each key does:

  • version: the stored preferences of each browser record the configuration version they were saved with. A new value discards them on the next load, so the new defaultLibraries reach users who already have saved preferences. Change it whenever you change defaults that live in the preferences.
  • defaultFonts: replaces the font list. The Inter entry is a web font: App.main adds its stylesheet to the page at startup (Graph.addFont), and choosing the font stores the URL in the cell style (fontSource), so other viewers of the diagram can load it too. Use customFonts to add fonts in front of the default list instead.
  • presetColors: the upper palette of the colour dialog, as hex codes without #.
  • defaultVertexStyle, defaultEdgeStyle: style keys copied onto every new shape and connector. defaultEdgeStyle replaces the built-in default object, so repeat the keys you want to keep (edgeStyle, jettySize, orthogonalLoop).
  • defaultLibraries: the libraries shown in the sidebar for new preferences. enabledLibraries limits the built-in libraries users can add through More Shapes and find in the shape search.
  • defaultGridEnabled: new diagrams start without a grid.

Reload with the browser cache disabled. With ?test=1 the console shows "Using global configuration" and any configuration errors. The same object can be pasted into Extras > Configuration to try it in one browser first, or sent in the configure message of an embedding.

Preferences in localStorage

Choices made in the UI are kept per browser by mxSettings (js/diagramly/Settings.js):

Key Contents
.drawio-config (Editor.settingsKey) The preferences: language, ui (theme), libraries, customLibraries, plugins, customFonts, recentColors, unit, pageFormat, darkMode, autosave, panel widths, collapsed sections, window states, the current edge style, and configVersion, the configuration version they were saved with
.configuration (Editor.configurationKey) The local configuration from Extras > Configuration
.sketch-config, .sketch-configuration The same two for the sketch theme. Only used when DRAWIO_PUBLIC_BUILD is not set; this repository's PreConfig.js sets it, so a deployment of it uses .drawio-config and .configuration for every theme
.mode The storage the user chose last

Related switches:

  • settingsName in the configuration renames both keys to .<name>-config and .<name>-configuration, so that several differently configured editors can share an origin.
  • window.mxLoadSettings = false (or configure=1, until the configuration arrives) stops the preferences from being loaded at startup.
  • local=1 disables localStorage entirely, so nothing is loaded or saved.
  • Extras > Configuration > Preferences shows the stored JSON and can reset it.

Drafts of unsaved diagrams are kept in IndexedDB, not in these keys.

See also

Clone this wiki locally