Layout Types
Root Layout
The root layout typically contains the<html> definition alongside the head and body tags. Any content defined in the root layout will remain the same, even as you live navigate across LiveViews.
- File location: Usually
root.html.heexin your layouts folder - Configuration: Declared on the router with
put_root_layout - Content injection: Calls
{@inner_content}to inject the content rendered by the layout - Rendering: Only rendered on the initial HTTP request
App Layout
The app layout is the dynamic layout part of your application. It often includes:- Menu and navigation
- Sidebar
- Flash messages
- Other dynamic UI elements
-
File location: From Phoenix v1.8, explicitly rendered by calling the
<Layouts.app />component -
Legacy: In Phoenix v1.7 and earlier, configured as part of
lib/my_app_web.ex
Overall, these layouts are found in
components/layouts and are embedded within MyAppWeb.Layouts.Root Layout Configuration
The root layout is rendered only on the initial request and has access to the@conn assign.
Router Configuration
LiveSession Configuration
You can also set the root layout via the:root_layout option in Phoenix.LiveView.Router.live_session/2:
Updating Document Title
Because the root layout from the Plug pipeline is rendered outside of LiveView, the contents cannot be dynamically changed. The one exception is the<title> of the HTML document.
Using @page_title
Phoenix LiveView special cases the @page_title assign to allow dynamically updating the title of the page.
In your LiveView:
Using live_title/1 Component
The Phoenix.Component.live_title/1 component supports adding automatic prefix and suffix to the page title:
MyApp – Latest Posts
Dynamic Updates
Update the title at any time by assigning topage_title:
Assigning
@page_title updates the document.title directly via JavaScript, and therefore cannot be used to update any other part of the base layout.Layout Limitations
The root layout is static during live navigation. Only the document title can be updated dynamically.Example: Root Layout
Example: App Layout
Using Different Layouts Per LiveView
You can specify different layouts for different LiveViews:In mount/3
In use Phoenix.LiveView
In live_session
Layout Best Practices
- Keep root layout static: Only dynamic content should be the page title
- Use app layout for navigation: Place menus, sidebars, and other dynamic UI in the app layout
- Group by live_session: Use
live_sessionto share layouts across related LiveViews - Set defaults wisely: Configure default layouts in
lib/my_app_web.exfor consistency - Update title for context: Change
@page_titleto reflect the current page or notification count
Common Patterns
Notification Count in Title
Breadcrumbs in App Layout
Flash Messages
Flash messages are typically shown in the app layout:Debugging Layouts
If your layout isn’t rendering as expected:- Check the router: Verify
put_root_layoutis called - Check live_session: Ensure the layout option is set correctly
- Inspect assigns: Use
IO.inspect(socket.assigns)to see available assigns - Verify @inner_content: Make sure your layout calls
{@inner_content}