Plugin Module¶
Your bundle's default export is a PluginModule — the lifecycle the host calls on you. Wrap it in definePlugin() so TypeScript types the object correctly.
definePlugin¶
method
definePlugin(mod: PluginModule): PluginModule
An identity helper that types your module as a PluginModule. Use it as the default export of your entry file.
PluginModule¶
type
The lifecycle contract. Only render is required.
interface PluginModule {
/** Called once after the manifest is verified, before the first render(). */
activate?(host: RBrowserHost): void | Promise<void>
/** Mount UI into the container. Called whenever the host panel re-mounts. */
render(container: HTMLElement, host: RBrowserHost): void | Promise<void>
/** Called when the plugin is unloaded. Must release resources. */
deactivate?(): void | Promise<void>
}
| Hook | When | Notes |
|---|---|---|
activate? |
Once, after the manifest is verified and before the first render. |
Good place for one-time setup; receives the RBrowserHost. |
render |
Every time the panel mounts. | You own the container's contents. Mount your UI (e.g. a React root) here. |
deactivate? |
On unload. | Release resources — unmount roots, remove listeners, clear timers. |
A typical React entry stores the root so render can remount cleanly and deactivate can tear down:
import * as ReactDOM from 'react-dom/client'
import { definePlugin } from '@rbrowser/plugin-sdk'
let root: ReactDOM.Root | null = null
export default definePlugin({
activate(host) {
console.log('[my-plugin] activate', host.info)
},
render(container, host) {
if (root) root.unmount()
root = ReactDOM.createRoot(container)
root.render(<App host={host} />)
},
deactivate() {
if (root) { root.unmount(); root = null }
}
})
Permission¶
type
The capabilities a plugin can request in its manifest. The host bridge is scoped to the granted set — calling an API you didn't request is a no-op.
type Permission =
| 'state:read' // getState / subscribe / all read hooks
| 'navigation:write' // host.navigate(...)
| 'highlight:write' // host.highlight.add / remove / clear
| 'storage:write' // host.storage.get / set / remove / keys / clear
See the Host Bridge for what each permission unlocks.