How a mountable library's CSS and JavaScript reach the browser.
A library picks a strategy with the :assets option of use PhoenixMountable:
use PhoenixMountable,
otp_app: :my_lib,
macro: :my_lib,
assets: {PhoenixMountable.Assets.Embedded, css: "priv/static/app.css", js: "priv/static/app.js"}Strategies shipped with PhoenixMountable:
PhoenixMountable.Assets.Embedded— bundles read and gzipped at compile time and served from memory under content-hashed URLs, the approach of Phoenix LiveDashboard, Oban Web and Lotus Web.PhoenixMountable.Assets.Static— a directory of files (a Vite, esbuild or React build, with an optional manifest) served under the mount.PhoenixMountable.Assets.Host— the host's own asset pipeline, for libraries styled by the host's Tailwind.
A strategy is any module implementing this behaviour, so a library can bring its own.
Entries
Each strategy describes the files a page needs as entries: a name, a URL
and a kind (:css, :js or :module). PhoenixMountable.Layout renders
them as tags with the request's CSP nonces and phx-track-static, and
url/2 returns one entry's URL.
Stale assets
After a deploy, a browser can keep running the previous bundle. When a
library LiveView connects, PhoenixMountable asks the strategy whether any of
the URLs the page tracks (phx-track-static) belongs to a previous build,
and reloads the page if so. Phoenix's own static_changed?/1 cannot see this
because it only knows the host's static manifest.
Summary
Callbacks
The entries of the strategy for a mount.
Validates the strategy options and computes its state.
Code to inject into the definition module, such as embedded file contents.
Routes to add under the mount path.
Whether any of the tracked URLs was produced by a previous build.
Functions
The asset entries of a mount, in order.
Whether the page that tracks tracked URLs runs assets of a previous build.
The URL of the asset entry name.
Types
Callbacks
@callback entries( state :: term(), PhoenixMountable.Mount.t(), path_fun :: (String.t() -> String.t()) ) :: [ entry() ]
The entries of the strategy for a mount.
path_fun turns a path relative to the mount into a full path, honouring
the endpoint's script name and the mount's :asset_host.
Validates the strategy options and computes its state.
Runs at compile time in the definition module. context has the
definition :module and the library's :otp_app. The state is stored in
every mount, so keep it small: file contents belong in inject/2.
Code to inject into the definition module, such as embedded file contents.
Routes to add under the mount path.
@callback stale?(state :: term(), PhoenixMountable.Mount.t(), tracked :: [String.t()]) :: boolean()
Whether any of the tracked URLs was produced by a previous build.
Functions
@spec entries(PhoenixMountable.Mount.t()) :: [entry()]
The asset entries of a mount, in order.
@spec stale?(PhoenixMountable.Mount.t(), [String.t()]) :: boolean()
Whether the page that tracks tracked URLs runs assets of a previous build.
@spec url(PhoenixMountable.Mount.t(), atom()) :: String.t()
The URL of the asset entry name.
<script src={PhoenixMountable.Assets.url(@mount, :js)} defer></script>