Events
React to document changes, selection changes, and the editor lifecycle.
The editor is an event emitter. Subscribe with editor.on(name, listener) and unsubscribe with
editor.off(name, listener). Every listener receives the event payload, which always contains the
editor.
const handleUpdate = ({ editor, transaction }) => {
console.log(editor.getMarkdown(), transaction);
};
editor.on("update", handleUpdate);
editor.off("update", handleUpdate);once(name, listener) subscribes for a single call. removeEventListeners(name) drops every
listener for one event, and removeListeners() drops all of them.
Events
| Event | Payload | When it fires |
|---|---|---|
beforeCreate | { editor } | In the constructor, before the editor state exists. |
create | { editor } | After the editor is created, and after mounting when element was passed. |
mount | { editor } | After the CodeMirror view is created in mount(). |
unmount | { editor } | Before the view is destroyed in destroy(). |
destroy | { editor } | After destroy() ran. |
update | { editor, transaction } | After a transaction changed the document. |
selectionUpdate | { editor, selection } | After a transaction changed the selection. |
focus | { editor } | After the editor gains DOM focus. |
blur | { editor } | After the editor loses DOM focus. |
beforeTransaction | { editor, transaction } | Before the mounted view applies a dispatched transaction batch. |
transaction | { editor, transaction } | After the mounted view applies a transaction batch, once per transaction. |
Transactions
beforeTransaction and transaction fire for every transaction dispatched to the mounted view,
including selection changes, effects, and transactions with no document changes. Both receive the
same CodeMirror Transaction object. Content changes made before mounting do not emit these events.
For a batch, all beforeTransaction listeners run before the batch is applied and see the old
editor state. Then transaction fires for each transaction in order, with the editor in the final
batch state. Read transaction.startState and transaction.state for each transaction’s own states.
These events observe transactions. They do not cancel or replace them.
editor.on("beforeTransaction", ({ transaction }) => {
console.log("before", transaction.startState.doc.toString());
});
editor.on("transaction", ({ transaction }) => {
console.log("after", transaction.state.doc.toString());
});Document changes
update fires for typing, pasting, and every command that changes the document. The payload
includes the CodeMirror transaction, which has the changes and the new state.
editor.on("update", ({ editor }) => {
save(editor.getMarkdown());
});Selection changes
selectionUpdate fires when the cursor or the selected range changes, including when a command
moves the selection.
editor.on("selectionUpdate", ({ selection }) => {
toolbar.setActive(selection.main.from !== selection.main.to);
});In React, useInksaneSelection() wraps this event. See the React guide.
Focus changes
focus and blur fire when the editor’s focus state changes. The payload contains only editor,
and editor.focused already reflects the new state when the listener runs. Focusing an editor
that already has focus does not emit another event. These events also work in read-only mode.
editor.on("focus", ({ editor }) => {
toolbar.setVisible(editor.focused);
});
editor.on("blur", ({ editor }) => {
save(editor.getMarkdown());
});Lifecycle
create runs once per editor. mount runs when the editor attaches to an element, which happens
right after creation when you pass element, or later when you call mount() yourself. destroy
runs when you tear the editor down.
An editor created with element emits mount while the constructor runs, before any listener can
subscribe. Create the editor without an element when you need to observe the mount:
const editor = new Editor({});
editor.on("mount", ({ editor }) => console.log("mounted", editor.isMounted));
editor.on("destroy", () => console.log("gone"));
editor.mount(document.getElementById("editor")); // logs "mounted true"For an editor that may already be mounted, check editor.isMounted instead.
Events on extensions
Extensions can declare handlers named after these events. The extension manager registers them
before beforeCreate, including handlers from child extensions. Higher-priority extensions run
first. Each handler receives { editor } followed by the event payload. All listeners are removed
when the editor is destroyed, after the destroy handlers run.