I ran into this same hurdle when adding Bodyguard to my navigation menu and needing to pass the controller :action for authz - and my navigation component is in the root template layout.
Now I am second guessing if I am going about this correct, as it seems there should be a Phoenix.LiveController.action_name
I ended up writing this horrendously coded helper function - but it works.
def get_action_name(conn) do
case Map.fetch(conn.private, :phoenix_live_view) do
{:ok, phoenix_live_view} ->
{_live_view, [action: action_name, router: _router], _} = phoenix_live_view
action_name
:error -> Phoenix.Controller.action_name(conn)
end
end