This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/document-authoring/events-and-integration.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Use events and integration APIs in Document Authoring

Before you start, ensure the Document Authoring library is installed and running. Refer to the getting started guide.

Document Authoring exposes editor events and runtime methods that help you integrate the editor into workflows such as autosave, document switching, and cleanup.

The example code omits error handling. Add it before using this code in production.

Listen for editor events

Use editor.on(), editor.off(), and editor.once() to subscribe to editor lifecycle events.

Document Authoring currently emits:

  • document.load — Fired when a document is loaded into the editor, including after switching documents.
  • content.change — Fired when document content changes through user edits or programmatic updates.

Autosave on content changes

Use content change events to save the current DocJSON whenever the document updates:

editor.on('content.change', async () => {
const doc = await editor.currentDocument().saveDocument();
localStorage.setItem('draft', JSON.stringify(doc));
});

To reduce save frequency, debounce the save logic:

let saveTimeout;
editor.on('content.change', () => {
clearTimeout(saveTimeout);
saveTimeout = setTimeout(async () => {
const doc = await editor.currentDocument().saveDocument();
await fetch('/api/save', {
method: 'POST',
body: JSON.stringify(doc),
});
}, 1000);
});

React to document loads

Use document.load to run logic whenever a new document becomes active in the editor:

editor.on('document.load', () => {
console.log('Document loaded successfully');
});

If you only need a one-time callback, use editor.once():

editor.once('document.load', () => {
console.log('Initial document is ready');
});

Remove listeners during cleanup

Use editor.off() to remove a specific handler or all handlers for an event:

const handleChange = async () => {
const doc = await editor.currentDocument().saveDocument();
localStorage.setItem('draft', JSON.stringify(doc));
};
editor.on('content.change', handleChange);
// Later
editor.off('content.change', handleChange);

You can also remove all listeners for an event:

editor.off('content.change');

Switch documents in an existing editor

Use editor.setCurrentDocument() to attach a different document to the same editor instance:

const imported = await docAuthSystem.import(fetch('/documents/sample.docx'), {
format: 'docx',
});
editor.setCurrentDocument(imported);

You can use editor.currentDocument() to access the current document any time:

const currentDoc = editor.currentDocument();
const pdf = await currentDoc.export({ format: 'pdf' });

When a new document is attached, the editor emits document.load for that document.

Use the editor and system together

Use editor.docAuthSystem() when you need the DocAuthSystem instance that created the editor:

const system = editor.docAuthSystem();
const emptyDocument = await system.createDocumentFromPlaintext('');
editor.setCurrentDocument(emptyDocument);

Destroy the editor safely

When your application no longer needs the editor, call editor.destroy(). If you’re done with the underlying system as well, destroy that too:

editor.destroy();
docAuthSystem.destroy();

A common cleanup pattern returns a function that unregisters listeners and destroys the editor:

const setupEditor = async (target) => {
const editor = await docAuthSystem.createEditor(target);
const handleLoad = () => console.log('loaded');
const handleChange = () => console.log('changed');
editor.on('document.load', handleLoad);
editor.on('content.change', handleChange);
return () => {
editor.off('document.load', handleLoad);
editor.off('content.change', handleChange);
editor.destroy();
};
};

Learn more