onInitialize, onResize, onUnload, and ready() — the complete lifecycle of a plugin from load to teardown
The lifecycle API covers every stage from when a plugin first loads to when it is torn down. Register all lifecycle handlers at the top level of your entry file before any async work.
Registers a handler that fires once when the plugin iframe has loaded and the runtime is ready. The handler receives the plugin's initial attrs, element dimensions, and the current animation state.
handler (function; required). Called with an InitContext object.voidThe attrs object contains every attribute declared in the manifest, fully resolved. Parameter variables referenced in Chalk (e.g., particles: n) are resolved to their current numeric value before being delivered.
The onInitialize handler can be async. The SDK waits for the returned Promise to resolve before delivering subsequent messages. If the promise rejects, the plugin enters an error state.
Signals the host that your plugin has rendered its first frame and is ready to be revealed. The host shows a loading indicator until ready() is called.
voidCall ready() inside onInitialize after your initial render is complete — not before painting, and not in a setTimeout. If ready() is not called within five seconds of initialisation, the host times out and shows an error state.
If your initialisation is async (loading assets, reading from storage), await the work before calling ready():
Registers a handler that fires whenever the internote layout causes the plugin element to change size.
handler (function; required). Called with a ResizeContext object.voidRegisters a handler that fires when the plugin element is removed from the internote — the student navigated away, the internote was closed, or the educator deleted the element.
handler (function; required). Called with no arguments.voidUse onUnload to cancel requestAnimationFrame loops, clear timers, disconnect ResizeObserver instances, close WebSocket connections, and free any other resources.
onUnload is not guaranteed to fire in all termination scenarios — a browser tab that is killed abruptly will not deliver the message. Do not rely on onUnload as the sole point of data persistence. Use internote.storage during normal operation and treat onUnload as a best-effort cleanup hook.