I found the solution by hit and trial:
live_session :authenticated,
on_mount: [{DerpyCoder.UserAuth, :ensure_authenticated},
{DerpyCoder.HeaderData, :fetch_existing_notifications}],
root_layout: {DerpyCoder.Layouts, :admin},
layout: {DerpyCoder.Layouts, :admin_header} do
...
end
admin.html.heex (Root Layout) [Same as root.html.heex]
<html>
...
<.only_function_components_allowed />
</html>
admin_header.html.heex (Live Components Allowed) [Same as app.html.heex]
<main>
<.flash_group flash={@flash} />
<.live_component module={DerpyCoder.SomeCustomLiveComponent} id={:yay} />
<%= @inner_content %>
</main>
Excerpt from documentation:
-
:root_layout
- The optional root layout tuple for the initial HTTP render to override any existing root layout set in the router. -
:layout
- The optional layout the LiveView will be rendered in. Setting this option overrides the layout viause Phoenix.LiveView
. This option may be overridden inside a LiveView by returning{:ok, socket, layout: ...}
from the mount callback
So by using a layout, along with a root layout, I was able to put the LiveComponent into the layout.
It seems the root layout is dead view, used for flushing out the styling and just works over HTTP.
While the layout is live, and thus allowed me to embed a Live Component.
Plus we can initialize the layout using on_mount and it has access to all the assigns from a page.
And one more approach is to just rely on on_mount, to handle data fetching and handle interactions.
As done by live_beats.
live_session :authenticated,
on_mount: [{LiveBeatsWeb.UserAuth, :ensure_authenticated}, LiveBeatsWeb.Nav] do
live "/:profile_username/songs/new", ProfileLive, :new
live "/:profile_username", ProfileLive, :show
live "/profile/settings", SettingsLive, :edit
end
defmodule LiveBeatsWeb.Nav do
import Phoenix.LiveView
use Phoenix.Component
def on_mount(:default, _params, _session, socket) do
{:cont,
socket
|> assign(active_users: MediaLibrary.list_active_profiles(limit: 20))
|> assign(:region, System.get_env("FLY_REGION") || "iad")
|> attach_hook(:active_tab, :handle_params, &handle_active_tab_params/3)
|> attach_hook(:ping, :handle_event, &handle_event/3)}
end
...
end
I’m not familiar with this approach, it’s my first time seeing attach_hook, so I will have to read through live_beats repo to understand it.
Thank you @cmo.
P.S. I am trying to combine both approach in my project, so I will update my findings here.