Events
The 18 events a plugin can subscribe to, and what each one carries.
On this page
Events are how you react to what someone does without checking on a timer. Subscribe with
tintero.events.on(). No permission is needed, because subscribing never leaves
your own frame. Tintero pushes events out to whichever plugins are running.
Subscribing
plugin.onActivate = async function () {
const refresh = async () => {
const count = await tintero.editor.getWordCount();
document.getElementById('n').textContent = count.words;
};
await refresh();
tintero.events.on('editor.activeDocumentChanged', refresh);
}; tintero.events.off() removes a handler. Handlers do not survive a reload,
because every start builds a brand new frame, so subscribe in onActivate every
time.
One event does not fit the table, because it hands you a whole object rather than a set of
named fields: debug.log gives your callback a single ConsoleEntry,
the same shape tintero.debug.getLogs() returns a list of.
project
project.loaded
Payload: projectId , projectName
project.saved
Payload: projectId
project.changed Fired with nothing attached.
file
file.opened
Payload: fileId , fileName
file.saved
Payload: fileId , fileName
file.closed
Payload: fileId
character
character.added
Payload: characterId , characterName
character.updated
Payload: characterId , characterName
character.deleted
Payload: characterId
worldbuilding
worldbuilding.added
Payload: elementId , elementType
worldbuilding.updated
Payload: elementId , elementType
worldbuilding.deleted
Payload: elementId
editor
editor.selectionChanged
Payload: documentId : string , from : number , to : number , empty : boolean
editor.activeDocumentChanged
Payload: documentId : string , name : string | null
plugin
plugin.activated Declared in the type definitions, but nothing in the app fires it. Subscribing does nothing.
plugin.deactivated Declared in the type definitions, but nothing in the app fires it. Subscribing does nothing.
storage
storage.changed
Payload: key ?: string
debug
debug.log Fired with a whole object rather than a field list. See the note above.
When events arrive
Your plugin only receives events once it has signalled that it is ready, which the SDK does for
you as soon as your script finishes running. Anything that happened before then is not replayed
Read the current state in onActivate rather than waiting for an event to tell you
what it already is.
storage.changed is the exception worth knowing: it fires on your plugin's
other surfaces, never on the one that performed the write. That asymmetry is what makes
it usable for keeping a sidebar panel and a full view in sync without a loop.