Phoenix LiveDashboard custom PageBuilder page cannot access init/1 session data in render/1. The page.info is nil and assigns don't contain the session values returned from init/1. menu_link/2 works fine but render/1 throws KeyError for expected session keys.
The session from init/1 is NOT automatically merged into socket assigns for render/1. It's only passed directly to menu_link/2 and to mount/3 if implemented. You must implement mount/3 to explicitly assign the session values to the socket:
@impl true
def init(opts) do
oban_name = Keyword.fetch!(opts, :oban)
title = Keyword.get(opts, :title, "Default Title")
{:ok, %{oban_name: oban_name, title: title}}
end
@impl true
def mount(_params, session, socket) do
# Session contains the return value from init/1
# Must explicitly assign it to socket for render/1 to access
{:ok, Phoenix.Component.assign(socket, session)}
end
@impl true
def menu_link(%{oban_name: oban_name, title: title}, _capabilities) do
# menu_link receives session directly - this works without mount/3
{:ok, title}
end
@impl true
def render(assigns) do
# Now assigns.oban_name and assigns.title are available
# because mount/3 assigned them
end
The flow is: init/1 → session stored → menu_link/2 receives session directly → mount/3 receives session as 2nd arg → you must assign to socket → render/1 receives socket.assigns