SquatchMail.Web.AssetController (SquatchMail v0.1.0)

Copy Markdown View Source

Serves SquatchMail's self-contained CSS/JS bundle (plus the logo PNG) with content-hashed, immutable-cached paths.

This follows the same pattern as Phoenix LiveDashboard's and Oban Web's asset plugs: the built priv/static/squatch_mail.{css,js} files (and the committed squatch_mail_logo.png) are read once at compile time into module attributes, an MD5 hash of each is computed as a compile-time constant, and that hash is embedded in the asset's URL (/assets/css-<md5>, /assets/js-<md5>). Because the path itself changes whenever the content changes, the response can be marked cache-control: public, max-age=31536000, immutable — the browser never needs to revalidate, and a fresh deploy naturally busts the cache by generating a new path.

This is a plain Plug, not a Phoenix.Controller — serving two static blobs doesn't need view/format negotiation, and Phoenix routers dispatch to either kind of module identically (get "/path", Module, :action).

The :md5 route parameter is not read by this plug; it exists only so a new build produces a new URL. The real, current hash used to build links is asset_path/1, computed from the actual file contents.

Missing build

priv/static/squatch_mail.{css,js} are generated by mix assets.build (see the alias in mix.exs) and are committed so hosts installing the hex package get them for free — they should always be present in a checkout of this repo or a published package. But reading them with File.read!/1 directly in module attributes would mean a missing build breaks mix compile for the entire dependent application, not just the dashboard — an unacceptable failure mode for a library. Instead, this module reads with File.read/2 at compile time and tolerates a nil result; asset_path/1 and call/2 both raise a descriptive RuntimeError only when the missing asset is actually requested, pointing at mix assets.build as the fix.

Summary

Functions

Returns the current asset path segment for asset (:css, :js, or :logo), e.g. "css-3f9c2a...". Used by SquatchMail.Web.Layouts to build the <link>/<script>/<img> src.

Functions

asset_path(atom)

@spec asset_path(:css | :js | :logo) :: String.t()

Returns the current asset path segment for asset (:css, :js, or :logo), e.g. "css-3f9c2a...". Used by SquatchMail.Web.Layouts to build the <link>/<script>/<img> src.

Raises if the asset hasn't been built yet — run mix assets.build.