Phoenix LiveComponent on the root.hml.leex

Hi folks, quick question: I’m trying to add a live_component into my root.html.leex, but I’m getting an error.

cannot convert component FooWeb.NavbarComponent with id nil to HTML.

A component must always be returned directly as part of a LiveView template.

This is my root.html.leex:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <%= csrf_meta_tag() %>
    <%= live_title_tag assigns[:page_title] || "Foo", suffix: " · Phoenix Framework" %>

    <link phx-track-static rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
    <script defer phx-track-static type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
  </head>
  <body>
    <%= live_component @socket, FooWeb.NavbarComponent %>

    <%= @inner_content %>
  </body>
</html>

And this is my navbar_component.html.leex:

<div class="navbar-fixed">
  <nav>
    <div class="container">
      <div class="nav-wrapper">
        <a href="#!" class="brand-logo">Logo</a>
        <a href="#" data-target="mobile-demo" class="sidenav-trigger"><i class="material-icons">menu</i></a>
        <ul class="right">
          <li><a href="sass.html">Sass</a></li>
          <li><a href="badges.html">Components</a></li>
        </ul>
        <ul class="sidenav" id="mobile-demo">
          <li><a href="sass.html">Sass</a></li>
          <li><a href="badges.html">Components</a></li>
          <li><a href="collapsible.html">Javascript</a></li>
          <li><a href="mobile.html">Mobile</a></li>
        </ul>
      </div>
    </div>
  </nav>
</div>
1 Like

LiveComponents must be children of a LiveView managed part of the dom. The root layout is never live. The earliest you can use components in is the layout for router mounted liveviews (live.html.leex) or even just the liveviews template for any other liveview used in otherwise static pages.

2 Likes

The one thing I haven’t been able to figure out – is there a way to associate live.html.leex to capture things from the mount or handle_params so they can be used for configuring a shared layout setup?

Afaik the live.html.leex runs in the context of the root liveview.

So to have a live component on the root of the page, I’ll need to have a live view view being the full body of the page.

Kinda. It still can’t be rendered by the root layout. But yes your layout would need to cover the whole body if you need a direct child of it to be live.

1 Like