From 21dd359b2fad1d4645a92eaabdfaff8bd3ecb82d Mon Sep 17 00:00:00 2001 From: Steffen Beyer Date: Sun, 24 May 2026 23:46:10 +0200 Subject: [PATCH] docs: clarify plugin hook registration Document that external plugin hooks are registered through global_js bundles and window.TribesPluginHooks rather than host-side colocated imports. --- AGENTS.md | 17 +++++++++-------- README.md | 15 +++++++++++++++ assets/js/aether.js | 3 ++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4e4de53..7821ed7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -362,20 +362,18 @@ when writing scripts inside the template**: } -- colocated hooks are automatically integrated into the app.js bundle +- colocated hooks are automatically integrated into the app.js bundle that imports the generated `phoenix-colocated/` module +- external Tribes plugin OTP apps are not auto-imported by the host `app.js` bundle; use `assets.global_js` plus `window.TribesPluginHooks` for plugin hooks - colocated hooks names **MUST ALWAYS** start with a `.` prefix, i.e. `.PhoneNumber` #### External phx-hook -External JS hooks (`
`) must be placed in `assets/js/` and passed to the -LiveSocket constructor: +External JS hooks (`
`) in Tribes plugins must be registered by a plugin JS bundle listed in `manifest.json` `assets.global_js`; the host merges `window.TribesPluginHooks` into the LiveSocket constructor: - const MyHook = { + window.TribesPluginHooks = window.TribesPluginHooks || {}; + window.TribesPluginHooks.MyHook = { mounted() { ... } - } - let liveSocket = new LiveSocket("/live", Socket, { - hooks: { MyHook } - }); + }; #### Pushing events between client and server @@ -635,6 +633,9 @@ checkout during development. For the full contract, see `import Tribes.UI.Components`, not a concrete provider module. - Declare browser assets in `manifest.json` under `assets.global_js` and `assets.global_css`; the host serves them through the plugin asset surface. +- Register plugin LiveView hooks from `assets.global_js` bundles via + `window.TribesPluginHooks`. Phoenix colocated hooks are not auto-imported from + external plugin OTP apps by the host `app.js` bundle. - Keep CSS selectors scoped to the plugin, normally with a plugin-specific root class. diff --git a/README.md b/README.md index c9226c4..fb88e1a 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,21 @@ aether/ See the host plugin docs in [PLUGINS.md](https://github.com/your-org/tribes/blob/master/docs/PLUGINS.md) for the full manifest and runtime contract. +## LiveView Hooks + +External plugins register browser hooks from JS bundles listed in +`manifest.json` `assets.global_js`: + +```javascript +window.TribesPluginHooks = window.TribesPluginHooks || {}; +window.TribesPluginHooks.AetherHook = { + mounted() {} +}; +``` + +The host loads plugin JS before connecting LiveSocket and does not auto-import +external plugin `phoenix-colocated/` modules into its `app.js` bundle. + ## Building for Release ```bash diff --git a/assets/js/aether.js b/assets/js/aether.js index 3c50d99..cdaa10d 100644 --- a/assets/js/aether.js +++ b/assets/js/aether.js @@ -3,7 +3,8 @@ // This file is served by the host at /plugins-assets/aether/aether.js // and included in the page layout if declared in manifest.json assets.global_js. // -// To register LiveView hooks: +// Register plugin LiveView hooks here. External plugin OTP apps are not +// auto-imported by the host's phoenix-colocated bundle. // // window.TribesPluginHooks = window.TribesPluginHooks || {}; // window.TribesPluginHooks["AetherHook"] = {