You can send a Phoenix Component in the controller assigns and use it in the root layout.
In your controller:
defmodule NewPhoenixWeb.PageController do
use NewPhoenixWeb, :controller
def home(conn, _params) do
render(conn, :home, my_root_component_content: apply(NewPhoenixWeb.Layouts, :custom_content_in_layout, [[]]))
end
def test(conn, _params) do
render(conn, :home, my_root_component_content: apply(NewPhoenixWeb.Layouts, :another_custom_content_in_layout, [[]]))
end
end
In your layouts.ex
:
defmodule NewPhoenixWeb.Layouts do
use NewPhoenixWeb, :html
embed_templates "layouts/*"
def custom_content_in_layout(assigns) do
~H"""
<p>content one</p>
"""
end
def another_custom_content_in_layout(assigns) do
~H"""
<p>content two</p>
"""
end
end
Finally, in your root.html.heex
(or any other layout file you want to use):
<div class="custom-content">
<%= @my_root_component_content %>
</div>
Also, you can use slots:
defmodule NewPhoenixWeb.Layouts do
slot :inner_block
def my_root_component(assigns) do
~H"""
<div>
<%= render_slot(@inner_block) %>
</div>
"""
end
end
In root.html.heex
:
<.my_root_component>
<%= @my_root_component_content %>
</.my_root_component>
There’s a similar question here: Phoenix 1.7 and inversion of control to render a sidebar