# `PhoenixKit.Install.JsIntegration`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v2.2.0/lib/phoenix_kit/install/js_integration.ex#L1)

Handles automatic JavaScript hooks integration for PhoenixKit installation.

This module:
- Copies `phoenix_kit.js` to the parent app's `priv/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 after
  `phoenix_kit.js` and before `app.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`.

# `add_js_integration`

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).

# `ensure_module_js_integration`

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.

# `update_js_file`

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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
