New Froala Editor v5.3.1 is here – Learn More
Froala Documentation
- Installation Guides
- Browser Support
- Languages Support
- Shortcuts
- Activation
- Examples
- Customize the Editor
- Use-cases
- Plugins
- APIs
- Development Frameworks
- Server Integrations
- Server SDKs
- Migration Guides
- Changelog
- Tutorials
- Froala Docs
- /
- SDKs
- /
- Node JS
- /
- Collaboration Overview
Node.JS Collaboration Overview
The Node.js SDK includes an optional backend for the editor's real-time collaboration plugin. It is split into four modules you compose as needed — a WebSocket relay for live peer sync, plus REST + SQLite stores for suggestions & comments, version snapshots, and offline saves. All four can share a single HTTP server and a single SQLite file.
| Module | Purpose |
|---|---|
Collaborative | Pure WebSocket relay. Groups clients by docId and broadcasts messages between peers. |
CollabPersistence | REST + SQLite for track-change suggestions and inline comments. |
VersionControl | REST + SQLite for named or automatic content snapshots. |
AsyncSave | REST + SQLite for saving/loading the latest content in offline (async) mode. |
Prerequisites
- Node.js 18 or later.
- Express — the
CollabPersistence,VersionControl, andAsyncSavemodules register their routes on an Express app. - better-sqlite3 — required by the three persistence modules. It ships as a regular dependency of the SDK and installs automatically
with npm install; no separate step is needed. - Client side — the editor's collaboration plugin manages all CRDT/sync state with Yjs and connects over a standard WebSocket. The server is a transparent relay and never parses message content.
The three persistence modules can share one SQLite file (default collab.db), so a full setup needs just one HTTP server and one database.
Quick start
A single Express-wrapped HTTP server hosts the WebSocket relay and all three REST stores, backed by one shared SQLite file.
const http = require('http');
const express = require('express');
const path = require('path');
const {
Collaborative,
CollabPersistence,
VersionControl,
AsyncSave,
} = require('wysiwyg-editor-node-sdk');
const app = express();
app.use(express.json());
// One SQLite file shared by all three persistence modules
const dbPath = path.join(__dirname, 'data', 'collab.db');
CollabPersistence.attachRoutes(app, { dbPath });
VersionControl.attachRoutes(app, { dbPath });
AsyncSave.attachRoutes(app, { dbPath });
// Optional: expose live relay stats
app.get('/health', (req, res) => res.json(Collaborative.getStats()));
// Share ONE HTTP server between REST and the WebSocket relay
const server = http.createServer(app);
Collaborative.attachToServer(server);
server.listen(3000, () => {
console.log('Collaborative backend on http://localhost:3000');
});
Use Collaborative.attachToServer(server) whenever the REST routes and the relay must share a port. Use Collaborative.createServer({ port }) only when the relay is the sole service on a port.
URL conventions
WebSocket : ws://<host>/{docId}
REST base : http://<host>/collab/{docId}/{resource} The {docId} used by the WebSocket connection must match the :docId in the REST routes. Document IDs are arbitrary strings; URL-encode any characters outside a-z 0-9 - _.
Connect the editor to the backend
Point the editor at the backend in the plugin config.
Real-time mode
set the WebSocket URL:
new FroalaEditor('#editor', {
pluginsEnabled: ['collaboration'],
realTimeConfig: {
syncUrl: 'ws://localhost:3000/my-doc-2024', // ws://<host>/{docId}
},
});
Async (offline) mode
omit syncUrl. The editor then persists through the AsyncSave endpoints instead of syncing live. The save plugin posts the content under the field name body (its default saveParam), which matches what POST /collab/:docId/content expects.
Suggestions, comments, and version history persist automatically through the REST modules once their routes are mounted.
For the complete endpoint and method reference, see the Collaborative Backend API Reference.
Do you think we can improve this article? Let us know.