Extension Points And Anti-Patterns
This document defines the supported ways to extend plugins with@anikitenko/fdo-sdk and what to avoid.
Supported Extension Points
Lifecycle Methods
init()- register handlers
- initialize stores
- perform backend runtime setup
render()- return UI source string for the iframe host render pipeline
renderOnLoad()- optional on-load string payload for UI runtime setup
Handler Registration
PluginRegistry.registerHandler(name, handler)- use for UI-to-backend calls
- keep handler names stable and explicit
- validate payloads at handler boundaries when needed
Store Usage
PluginRegistry.useStore("default")for scoped in-memory statePluginRegistry.useStore("json")for scoped persistent state- requires host capability grants:
storage+storage.json
- requires host capability grants:
createStorageCapabilityPreset("storageJSON")for a curated JSON-storage capability presetcreateStorageCapabilityBundle("json")for custom backend-driven storage capability bundle creationPluginRegistry.registerStore(name, storeOrFactory)for custom store integrationsPluginRegistry.configureStorage({ rootDir })for persistent storage rootPluginRegistry.configureCapabilities({ granted })for host-managed grants to privileged SDK features
UI Extensions
QuickActionMixinfor quick action definitionsSidePanelMixinfor side panel definitionslistRenderOnLoadTemplates(...)/getRenderOnLoadTemplate(...)for deterministic host/editor on-load templates
Error Handling
@handleError()for controlled error handling behavior- optional
errorUIRendererfor render fallback UI formatPrivilegedActionError(response, options?)for stable privileged-action error messagesgetInlinePrivilegedActionErrorFormatterSource()forrenderOnLoad()string runtimes
Logging And Diagnostics
this.log/info/warn/debug/verbose/silly(...)in plugin classesthis.error(error)for error logsthis.event(name, payload)for structured events with correlation IDsPluginRegistry.DIAGNOSTICS_HANDLER("__sdk.getDiagnostics") for host diagnostics requests overUI_MESSAGEcreatePluginDoctorReport(diagnostics, options?)for host-side structured triage findings derived from diagnosticscreatePluginDoctorPanelModel(report, options?)for prioritized, sectioned panel-ready findings with exact-fix text
Anti-Patterns To Avoid
Runtime Boundary Violations
- do not use iframe-only globals in backend/bootstrap paths
- do not assume browser APIs are available in plugin backend runtime
Lifecycle Misuse
- do not perform heavy dynamic setup in
render() - do not rely on constructor side effects for host/runtime integration
- do not override serialization helpers unless intentionally changing transport behavior
Storage Misuse
- do not assume JSON store is available without configured storage root
- do not assume privileged features are available without host capability grants
- do not rely on unscoped key names for cross-plugin shared state
- do not depend on private store internals (
_-prefixed fields)
Error Handling Misuse
- do not use brittle UI-only helpers in backend error fallback paths
- do not let custom error UI throw without fallback expectations
Contract Drift
- do not depend on non-exported internals as public API
- do not infer plugin contract behavior from tests only
- use documented contract sources:
README.mddocs/RENDER_RUNTIME_CONTRACT.mddocs/ARCHITECTURE.mddocs/API_STABILITY.md- this file
Practical Checklist
- implement
init()andrender()explicitly - define complete
metadatawith valid BlueprintJS v6icon - prefer
metadata.idfor stable plugin scope - register handlers in
init() - use scoped stores through
PluginRegistry - log lifecycle and handler paths with structured events when useful