Serve LiveView from router

Hello! I’m learning LiveView, and developed a example app.

I’m using for this question the example from
https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html

If I serve like this :

Temperature Control

<%= live_render(@conn, AppWeb.ThermostatLive) %>

or, this way:

defmodule AppWeb.ThermostatController do

import Phoenix.LiveView.Controller

def show(conn, %{“id” => id}) do
live_render(conn, AppWeb.ThermostatLive)
end
end

It’s works fine, but if I serve it from the router like this:

defmodule AppWeb.Router do
use Phoenix.Router
import Phoenix.LiveView.Router

scope “/”, AppWeb do
live “/thermostat”, ThermostatLive
end
end

The liveSocket doesn’t connect but the page is rendered from the AppWeb.ThermostatLive render function.

What do I’m missing?

When you are rendering your LiveView through controller, you are using app.html.eex layout view. That is actually a just a regular app view, with injected live view.

When you are mounting LiveView directly in the router, you should specify, which default view it should use.

you can provide, but there you will not have access to @conn object in the template anymore

live “/thermostat”, ThermostatLive,  layout: {AppWeb.LayoutView, "app.html"}

it is better if you define separate layout view for LiveView (live.html.leex) and there you will have access to @socket
My explanation is not the best, I am just working with LiveViews myself :slight_smile:
Here you will find better information https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#module-live-layouts

3 Likes