ryanzidago
How to override the default app layout for a specific LiveView?
How can I set a specific layout for a specific LiveView?
I have the following route:
scope "/:locale", MyAppWeb do
pipe_through :browser
live "/", LandingPageLive, :home
# some other routes
end
And this in MyAppWeb:
def live_view do
quote do
use Phoenix.LiveView,
layout: {MyAppWeb.Layouts, :app}
on_mount MyAppWeb.SetLocale
unquote(html_helpers())
end
end
This means that by default all LiveViews have the app layout.
How can I make it so that the LandingPageLive does not have the app layout (which contains a sidebar)?
Looking at the documentation, I see here that there are two ways to override the default layout:
- live_session which I do not have
- :layout option when mounting the LiveView.
Since I don’t have a live_session in my router, I’m going for the second option using {MyAppWeb.Layouts, :landing_page}:
defmodule MyAppWeb.LandingPageLive do
use MyAppWeb, :live_view
use Gettext, backend: MyAppWeb.Gettext
@impl LiveView
def mount(params, _session, socket) do
socket = assign(socket, layout: {MyAppWeb.Layouts, :landing_page})
{:ok, socket}
end
@impl LiveView
def render(assigns) do
~H"""
Welcome!
"""
end
end
And I have a the following directory structure:
lib/my_app_web/
├── components
│ ├── core_components.ex
│ ├── layouts
│ │ ├── app.html.heex
│ │ ├── landing_page.html.heex
│ │ └── root.html.heex
│ ├── layouts.ex
│ └── sidebar.ex
├── live
│ ├── landing_page_live.ex
However, I get this error:
invalid value for reserved key :layout in Phoenix.Template.render/4 assigns.
:layout accepts a tuple of the form {LayoutModule, "template.extension"},
got: {ClipboardWeb.Layouts, :landing_page}
Looks like I need to pass a string:
defmodule MyAppWeb.LandingPageLive do
use MyAppWeb, :live_view
use Gettext, backend: MyAppWeb.Gettext
@impl LiveView
def mount(params, _session, socket) do
socket = assign(socket, layout: {MyAppWeb.Layouts, "landing_page.html"})
{:ok, socket}
end
@impl LiveView
def render(assigns) do
~H"""
Welcome!
"""
end
end
Not enough:
no "landing_page.html" html template defined for ClipboardWeb.Layouts (the module exists but does not define landing_page.html/1 nor render/2
My MyAppWeb.Layouts looks like so:
defmodule MyAppWeb.Layouts do
@moduledoc """
This module holds different layouts used by your application.
See the `layouts` directory for all templates available.
The "root" layout is a skeleton rendered as part of the
application router. The "app" layout is set as the default
layout on both `use MyAppWeb, :controller` and
`use MyAppWeb, :live_view`.
"""
use MyAppWeb, :html
alias MyAppWeb.Sidebar
embed_templates "layouts/*"
end
Thus I assume that it embeds all templates under the lib/my_app_web/components/layouts/.
What’s the expectation here?
Marked As Solved
rhcarvalho
The return value from mount can also set the layout:
It must return either
{:ok, socket}or{:ok, socket, options}, whereoptionsis one of:
:temporary_assigns- a keyword list of assigns that are temporary and must be reset to their value after every render. Note that once the value is reset, it won’t be re-rendered again until it is explicitly assigned:layout- the optional layout to be used by the LiveView. Setting this option will override any layout previously set viaPhoenix.LiveView.Router.live_session/2or onuse Phoenix.LiveView
Also Liked
LostKobrakai
This is wrong. You don’t assign the layout as an assign on the socket, but it’s an option on the return tuple of mount.
def mount(params, _session, socket) do
{:ok, socket, layout: {MyAppWeb.Layouts, :landing_page}}
end
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









