How to Extend Lifecycle Hooks to LiveComponents in Phoenix LiveView

Hi everyone,

I’m currently working on a Phoenix LiveView project and I’ve encountered a challenge that I hope someone can help me with. I need to extend a lifecycle hook from the parent LiveViews to their child LiveComponents, but I’m struggling to find a clean and effective way to do this.

Context

I have several LiveViews and I want to attach a hook that should be executed for all handle_event events, including those in child LiveComponents. Here’s a simplified version of my setup:

router.ex

...
    live_session :name, on_mount: {MyApp.Live.Session, :default} do
      live "/name", MyApp.Index, :index
    end
...

live_auth.ex

defmodule MyApp.Live.LiveSession do

  import Phoenix.Component
  import Phoenix.LiveView

  def on_mount(:default, _params, session, socket) do
    login_time = session["login_time"]
    if session_expired?(login_time) do
      {:halt,
       socket |> put_flash(:warn, "...") |> redirect(to: "/auth/oidc")}
    else
      {:cont,
       socket
       |> assign(:login_time, login_time)
       |> attach_hook(:check_session, :handle_event, &check_session/3)}
    end
  end

  defp check_session(event, _params, socket) do
    login_time = socket.assigns.login_time

    if session_expired?(login_time) do
      {:halt,
       socket |> put_flash(:warn, "...") |> redirect(to: "/auth/oidc")}
    else
      {:cont, socket}
    end
  end

  defp session_expired?(login_time) do
    if DateTime.diff(DateTime.utc_now(), login_time, :second) > 8 * 3600 do
      true
    else
      false
    end
  end
end

The Problem

The hook works perfectly for events in the parent LiveView, but it doesn’t get triggered for events in the child LiveComponents. I want to ensure that the session check is performed for all events, including those in the LiveComponents.

Any guidance or examples on how to achieve this would be greatly appreciated. Thank you!