28 August 2025

Universal assigns with Phoenix LiveView


Working with LiveView, we often face the need to make certain values available in all components - for example, the domain host, locale or feature flags. The good news is that with a small plug + an on_mount hook, that can be achieved fairly easily.

The pattern

  1. Plug: capture context from the request.
  2. Session: store small values (tenant name, locale code, user token).
  3. on_mount: hydrate LiveView assigns from that session.

Plug example

# inside a plug
locale = conn.params["locale"] || "en"

conn
|> put_session(:locale, locale)

This way, every WebSocket connection starts with enough context to restore state.

on_mount

Create a small helper module under lib/myappweb/live/, for example:

defmodule MyAppWeb.InitAssigns do
  import Phoenix.LiveView

  def on_mount(:default, _params, session, socket) do
    socket =
      socket
      |> assign_new(:locale, fn -> session["locale"] end)

    {:cont, socket}
  end
end

This will extract the locale value from the session and insert it into the socket. You then hook this module into your router with a live_session:

live_session :default,
  on_mount: [{MyAppWeb.InitAssigns, :default}] do
    live "/", HomeLive
    live "/dashboard", DashboardLive
end

Et Voila - now every LiveView has @locale assign that you can use directly, without repeating code.

By combining plugs, sessions, and on_mount, you can establish universal assigns. This pattern makes your LiveViews cleaner: instead of repeating boilerplate in every mount, you centralize it once and reuse it everywhere.

Related posts