In normal controllers, to overwrite the root layout I would use
conn
|> put_layout(false)
|> put_root_layout(false)
|> render("any.html", foo: bar)
to don’t use root.html.heex
or anything else.
How can I achieve that with LiveView?
In normal controllers, to overwrite the root layout I would use
conn
|> put_layout(false)
|> put_root_layout(false)
|> render("any.html", foo: bar)
to don’t use root.html.heex
or anything else.
How can I achieve that with LiveView?
AFAIK there are a few ways to do this depending on what you want to do and how you’re rendering the LiveView.
To remove or replace the "live.html"
layout on an individual LiveView just return from your mount/3
callback with {:ok, socket, layout: false}
or {:ok, socket, layout: {LayoutView, "custom_layout.html"}
.
You can also pass an alternative layout as an option to use Phoenix.LiveView
.
defmodule MyAppWeb.PageLive do
use Phoenix.LiveView, layout: {LayoutView, "custom_layout.html"}
end
You can perform this override in the def live_view
block of my_app_web.ex
if you want to apply it app-wide whenever you use MyAppWeb, :live_view
To override the "root.html"
layout you can pass :root_layout
as an option to live_session
in your router.ex
scope "/", MyAppWeb do
pipe_through :browser
live_session :default, root_layout: false do
# or root_layout: {LayoutView, :custom_layout}
live "/page", PageLive
end
end
If you are rendering your LiveView from a controller with live_render(conn, PageLive)
then you can do it the old-fashioned way you already know.
To override the
"root.html"
layout you can pass:root_layout
as an option tolive_session
in yourrouter.ex
This did it. Thank you very much.
callback with
{:ok, socket, layout: false}
or
Does actually not work. It expects an alternative layout as you described with
{:ok, socket, layout: {LayoutView, “custom_layout.html”}
which then could be empty.
It definitely works for me. I have used it in a project and made sure to test each of these methods before answering. I’m testing it right now with both
live_render
ed liveviews and router mounted liveviews and both are working. It’s only good for changing the inner layout, not the root layout, fwiw. Also, this is v.0.17.10
Edit: you’re right that layout: false
does not work as an option for use Phoenix.LiveView
, that is the only one I did not directly test : ) But it does work in the return value for mount/3
. Correcting the original post for posterity
Sorry, I quoted the wrong part, within the LiveView page your are correct, this works. The part where I got the error message was:
use Phoenix.LiveView, layout: false
With the message:
:layout expects a tuple of the form {MyLayoutView, "my_template.html"}, got: false
Testing :layout
on a live_view mount
in Phoenix 1.7.1.
The error message is leading to a View concept:
:layout expects a tuple of the form {MyLayoutView, :my_template} or false, got: :menu
But it’s perfectly happy with {ProjectWeb.Layouts, :menu}
:
def mount(_params, _session, socket) do
{:ok, socket, layout: {ProjectWeb.Layouts, :menu}}
end
provided, a menu.html.heex
sits in the layouts
folder (and therefore embedded by layouts.ex
which defines ProjectWeb.Layouts
module).