DocumentationDocumentation
API reference/Python API

Events and notifications

Find the public interface for pushing events from Python to pages.

Events tell the page what just happened

Use events for task completion, import results, or lightweight notifications. If a page opened later must read the current value, use State API; if the page must request Python work and await a result, use Action API. Events do not replace persistent state or request/reply.

event.emit: send an add-on event

WebBridgeEvent
Public definitions
class WebBridgeEvent (Protocol):
  emit(self, name: 'str', payload: 'WebEventPayload' = None) -> 'None'

Use plugin.bridge().event.emit(name, payload). Names must use plugin.* and match exactly on both sides. payload defaults to None and accepts JSON data. Returns None, not a recipient count or confirmation of display.

WebEventPayload
Public definitions
WebEventPayload = str | int | float | bool | None | list['WebJSONValue'] | dict[str, 'WebJSONValue']

Do not include Blender objects, file handles, or raw bytes in payloads. For images and large files, first Publish resource references. Sending targets documents subscribed to that name within the current add-on client; it is not a cross-add-on broadcast.

Call after the operation completes; plugin is a bound client
python
plugin.bridge().event.emit(
    "plugin.my_addon.task_finished",
    {"label": "预览准备完成", "count": 3},
)

Subscribe before triggering work

Events queue for current subscribers without a historical replay guarantee. Subscribe before enabling the task so sending cannot precede listening. To restore results after reopening, store results in state and use events only as notifications.

External page module; enable the task entry point after mounting finishes
javascript
async function mountTaskNotice(output) {
  const webui = window.acquireNexusWebUI();
  const subscription = await webui.event.on(
    "plugin.my_addon.task_finished",
    (payload, meta) => {
      if (meta.dropped) {
        output.textContent = "部分通知已丢弃,请重新读取任务状态。";
        return;
      }
      const label = payload?.label;
      output.textContent = typeof label === "string" ? label : "任务状态已更新。";
    },
  );
  return () => subscription.release();
}

Await mountTaskNotice, retain its cleanup function, and invoke it on unmount, handling cleanup failures. If unmount occurs before subscription finishes, clean up immediately after it succeeds rather than discarding the pending Promise. See Events and connection lifecycle guide.

Successful sending is not successful workflow acceptance

With no matching subscribers, there is no visible notification. Closing, reloading, or disconnecting can prevent an old document from receiving events. Do not use events as guaranteed delivery records or claim users saw results merely because emit did not throw.

Application logic must provide explicit task results. A custom ok field in an event is only application data. Coalesce high-frequency progress updates; current values are usually better expressed as state.

Errors, names, and lifecycle

Invalid names, non-JSON payloads, and disposed clients can fail. Preserve original errors for diagnosis. Do not send in reserved namespaces or impersonate connection signals such as ready or disconnected.

Python does not register an event handler before emitting; emit sends. Page listeners must unsubscribe. Use lifecycle.on for connection notifications and event.on for add-on events, releasing both kinds of handle when no longer needed. Disabling an add-on still requires cleanup of its tasks and clients.

Definitions come from the public API baseline; scope, subscriptions, and release are checked against event dispatch and public page types.

Back to API reference · All topics