Nextcloud app that integrates the draw.io (diagrams.net) diagram editor. Users can create and edit .drawio diagrams and .dwb whiteboards directly within Nextcloud. The draw.io editor runs in an iframe and communicates with the Nextcloud backend via postMessage.
- App ID:
drawio - Namespace:
OCA\Drawio - License: AGPL
- Nextcloud compatibility: 33 only (min-version and max-version in
appinfo/info.xml) - Version: defined in both
appinfo/info.xmlandpackage.json(keep in sync)
appinfo/ App manifest (info.xml) and route definitions (routes.php)
lib/ PHP backend
AppConfig.php Configuration manager (get/set for all admin settings)
AppInfo/ Application bootstrap, DI registration, MIME types
Controller/ EditorController (file CRUD, revisions) & SettingsController
Listeners/ Event handlers (file delete cleanup, reference widget loader, template creator)
Reference/ Reference Provider for inline diagram previews in Text/Collectives/Talk
Migration/ MIME type registration/unregistration repair steps
Preview/ Thumbnail generation from cached PNG previews
Settings/ Admin settings panel registration
src/ JavaScript source (webpack entry points)
editor.js Editor page – iframe communication, save/load, autosave, previews
main.js File list integration – file actions, new file menu entries
settings.js Admin settings form
reference.js Reference widget registration for inline diagram previews
components/ Vue components (DrawioReferenceWidget.vue)
js/ Compiled webpack output (do not edit directly)
templates/ PHP templates for editor and settings pages
css/ Stylesheets (main, editor, settings)
img/ SVG icons (app, app-dark, drawio file type, whiteboard)
l10n/ Translations (~100 languages, managed in-repo)
scripts/ Build/maintenance scripts (extract-strings.js, dev-setup.sh, dev-rebuild.sh)
.github/workflows/ CI: release pipeline (release.yml), stale bot (stale.yml)
- Node.js 20+
- npm
npm ci # Install dependencies (use ci, not install)
npm run build # Production build (webpack, output to js/)
npm run dev # Development build
npm run watch # Development build with file watching
npm run extract-strings # Extract translatable strings to l10n/source-strings.jsonSee DEV.md for full details. Quick start:
npm ci
./scripts/dev-setup.sh # builds, starts NC 33 + MariaDB, enables the appThen open http://localhost:8088 (admin / admin). PHP changes are live (volume-mounted); JS changes require npm run build.
Important: Do not change the app version in info.xml during development — it will break the Nextcloud instance.
- User clicks a
.drawio/.dwbfile →main.jsregisters file actions via@nextcloud/files - Editor page loads →
editor.jscreates iframe pointing to draw.io (embed.diagrams.net or self-hosted) - draw.io ↔ Nextcloud communication via
postMessage/ "remote invoke" protocol - Save/load operations go through
EditorControllerPHP endpoints - PNG previews are generated client-side and saved via
savePreviewendpoint
When a draw.io editor URL is pasted into Nextcloud Text, Collectives, Talk, Notes, or Deck:
DrawioReferenceProvidermatches the URL and resolves file metadata + preview imageDrawioReferenceListenerloads thedrawio-referenceJS bundle on demandreference.jsregisters a Vue widget (DrawioReferenceWidget.vue) for thedrawio_diagramrich object type- The widget renders an inline card with the diagram thumbnail and an "Open in Draw.io" link
- Smart Picker (
/menu) lists "Draw.io Diagrams" viaISearchableReferenceProvider
RegisterTemplateCreatorListener registers .drawio and .dwb as file types in the Nextcloud "+" new file menu via RegisterTemplateCreatorEvent. This also enables creating diagrams as Text document attachments (stored in .attachments.{docId}/ folders). The editor detects attachment paths on close and redirects to the parent document.
| Method | URL | Controller Method |
|---|---|---|
| GET | /edit |
EditorController@index |
| GET | /ajax/load |
EditorController@load |
| GET | /ajax/getFileInfo |
EditorController@getFileInfo |
| GET | /ajax/getFileRevisions |
EditorController@getFileRevisions |
| GET | /ajax/loadFileVersion |
EditorController@loadFileVersion |
| POST | /ajax/new |
EditorController@create |
| PUT | /ajax/save |
EditorController@save |
| POST | /ajax/savePreview |
EditorController@savePreview |
| POST | /ajax/settings |
SettingsController@settings |
- Concurrency: ETags for optimistic conflict detection; ILockingProvider for file locking
- Sharing: Supports both authenticated users and public share tokens (separate code paths)
- Configuration: All admin settings stored via Nextcloud's config API (
AppConfig.php) - MIME types:
application/x-drawio(.drawio) andapplication/x-drawio-wb(.dwb), registered in repair steps - Translations: Use
t('drawio', 'key')in JS (@nextcloud/l10n),$l->t('key')in PHP templates, and$this->trans->t('key')in PHP controllers - Frontend globals:
OCA.DrawIOnamespace used inmain.js;editor.jsuses an IIFE withOCAparameter - Reference Provider:
DrawioReferenceProviderextendsADiscoverableReferenceProviderand implementsISearchableReferenceProvider; rich object type isdrawio_diagram - Template Creator:
.drawio/.dwbregistered viaRegisterTemplateCreatorEvent+TemplateFileCreator
The create/edit flow — creating a .drawio/.dwb file from the "+" menu, then clicking it to open in the draw.io editor — depends on all of the following MIME type registration steps working together. Removing or skipping any of these breaks the basic flow (files download instead of opening in the editor):
-
Config files (
RegisterMimeType::registerForNewFiles)- Writes to
config/mimetypemapping.json(extension → MIME type) - Writes to
config/mimetypealiases.json(MIME type → icon alias)
- Writes to
-
Filecache update (
RegisterMimeType::registerForExistingFiles)- Updates DB filecache so existing
.drawio/.dwbfiles have the correct MIME type
- Updates DB filecache so existing
-
Icon copy (
RegisterMimeType::copyIcons)- Copies
drawio.svganddwb.svgtocore/img/filetypes/
- Copies
-
UpdateJS (
$this->updateJS->run(...))- Regenerates
core/js/mimetypelist.jswith drawio MIME type entries
- Regenerates
-
Runtime registration (
Application::boot)$detector->registerType("drawio", "application/x-drawio")$detector->registerType("dwb", "application/x-drawio-wb")
-
Self-healing (
Application::ensureMimeTypeAssets)- Re-runs all of the above when NC version changes or icons are missing from core
- This fixed #119
Steps 3 and 4 modify Nextcloud core files, which triggers integrity check warnings (#70). This is a known Nextcloud limitation — there is no public API for apps to register MIME type icons without modifying core (see nextcloud/server#10131). Do not remove steps 3 or 4 to fix the integrity warnings — it breaks the create/edit flow.
After any change to MIME type registration, always verify:
- Run
./scripts/dev-setup.shfor a fresh NC instance - Create a new
.drawiofile from the "+" menu → file should appear in the file list - Click the file → should open in the draw.io editor (NOT download)
- Edit, save, and close → changes should persist
- Re-open the file → saved content should be there
- PHP follows PSR-2/PSR-12 style
- JavaScript uses ES6+ imports with
@nextcloud/*packages - Vue 2 Single File Components (
.vue) used for reference widget (src/components/) @nextcloud/vuev8 providesregisterWidgetfor reference widgets- No linter or formatter is configured
- No test framework is set up
Managed in-repo. The l10n/ directory contains .js and .json files for ~100 languages. These are the runtime format Nextcloud loads directly.
- Run
npm run extract-stringsto regeneratel10n/source-strings.json— the canonical list of all English source strings - The script scans
src/*.js,templates/*.php, andlib/**/*.phpfor translation function calls - To add/update a translation: edit the corresponding
l10n/{lang}.jsandl10n/{lang}.jsonfiles directly - The
.jsformat usesOC.L10N.register("drawio", {...}, "pluralForm")and the.jsonformat uses{"translations": {...}, "pluralForm": "..."}
Handled by .github/workflows/release.yml on version tags (v*):
- Checkout → npm ci → npm run build
- Create zip/tar.gz archives (excluding dev files)
- Upload to GitHub Releases
- Sign with RSA key and publish to Nextcloud App Store