Handles automatic JavaScript hooks integration for PhoenixKit installation.
This module:
- Copies
phoenix_kit.jsto the parent app'spriv/static/assets/vendor/ - Adds a
<script>tag to the root layout so hooks are loaded before LiveSocket
The JS file defines window.PhoenixKitHooks which is spread into LiveSocket's
hooks object in app.js: hooks: { ...window.PhoenixKitHooks, ...colocatedHooks }
External module hooks
External modules declare prebuilt hook bundles via js_sources/0. The
:phoenix_kit_js_sources compiler concatenates those into
priv/static/assets/vendor/phoenix_kit_modules.js on every compile and folds
their hooks into window.PhoenixKitHooks. This module:
- registers that compiler in the parent app's
mix.exs, - adds a single (stable)
<script>tag for the aggregate file afterphoenix_kit.jsand beforeapp.js, - seeds an empty aggregate file so the tag doesn't 404 before the first compile.
The tag never changes as modules come and go — only the file's content does — so
module JS stays zero-config, exactly like css_sources/0.
Summary
Functions
Copies phoenix_kit.js to the parent app's static vendor directory and adds a script tag to the root layout.
Ensures the external-module JS integration is wired: an aggregate file is
seeded, and the root layout has the (stable) module-hooks <script> tag.
Ensures the host root layout stamps the saved theme before first paint.
Updates the JS file in the parent app's static vendor directory.
Called during mix phoenix_kit.update to keep hooks in sync.
Functions
Copies phoenix_kit.js to the parent app's static vendor directory and adds a script tag to the root layout.
Safe to run multiple times (idempotent).
Ensures the external-module JS integration is wired: an aggregate file is
seeded, and the root layout has the (stable) module-hooks <script> tag.
Registering the :phoenix_kit_js_sources compiler itself is NOT done here
— see PhoenixKit.Install.Common.ensure_compilers_registered/2, called
once by the install/update tasks alongside :phoenix_kit_css_sources
(touching mix.exs's :compilers list from two separate calls corrupts
the second one; see that function's doc).
Idempotent. Called at install and at mix phoenix_kit.update, so hosts that
installed before this feature pick it up on their next update.
Ensures the host root layout stamps the saved theme before first paint.
Renders PhoenixKitWeb.Components.ThemeBootstrap at the top of <head>.
Without it, admin pages served under the host's root layout paint in the
default theme and swap after load — the one page class the kit's own
layouts (which all render the bootstrap themselves) cannot cover.
Skipped when the layout already renders the component. A stock
phx:theme script (phx.new 1.8) is NOT a substitute: it treats
"system" as "remove data-theme", which is how branded hosts flashed
daisyUI's default over the configured pair. Those layouts still get
the bootstrap, injected just before </head> so it runs after the
stock script and the configured pair wins.
Safe to run multiple times (idempotent). Called from both install and
mix phoenix_kit.update, so existing hosts pick it up on upgrade.
Updates the JS file in the parent app's static vendor directory.
Called during mix phoenix_kit.update to keep hooks in sync.
Belt-and-suspenders only — the :phoenix_kit_js_sources compiler now
re-vendors this same file on every mix compile, so it self-heals even if
this never runs again. This copy exists for the immediate feedback of
running update itself, and raises loudly (Mix.raise/1) instead of
logging a warning that the caller's return value goes unchecked, since a
silently-stale hooks file breaks every PhoenixKit JS interaction with no
error anywhere in sight.