Is it possible to create a global modal using LiveView?

The code the generator create uses the modal within the same liveview.

live "/listings", ListingLive.Index, :index
live "/listings/new", ListingLive.Index, :new

I found a guide that also shows some examples, he too has to use the same liveview, otherwise the modal doesn’t know what to render and go back to when clicking outside of the modal.

live "/counter", CounterLive, :show
live "/counter/confirm-boom", CounterLive, :confirm_boom

What I’m trying to build is a register form inside of the modal. People click on Sign Up anywhere on the site and this modal pops up. Is this possible with liveview, or should I create the form clientside entirely using alpine?

Could you put the modal in the root template?

I tried that but ran into some blocks.

  1. How do I generate the empty @user changeset so the register form has something to work again, in every single liveview?
  2. What would I use in the return_to option? The phoenix generator can just go back to /products from /products/123.
<main role="main">
  <p class="alert alert-info" role="alert"
    phx-click="lv:clear-flash"
    phx-value-key="info"><%= live_flash(@flash, :info) %></p>

  <p class="alert alert-danger" role="alert"
    phx-click="lv:clear-flash"
    phx-value-key="error"><%= live_flash(@flash, :error) %></p>

  <%= @inner_content %>

  <h1><%= @live_action %></h1>
</main>

<%= if @live_action in [:register] do %>
  <%= live_modal ZZZWeb.RegisterLive,
    id: "register",
    title: @page_title,
    user: @user,
    return_to: Routes.listing_index_path(@socket, :index) %>
<% end %>

Part of me is thinking I need to muck around with the code generator in zzz_web.ex and create a @user object there, and somehow put it into the default assigns for every liveview.

  def live_view do
    quote do
      use Phoenix.LiveView,
        layout: {ZZZWeb.LayoutView, "live.html"}

      unquote(view_helpers())
    end
  end

But it can’t be this tricky right? I must be looking in the wrong place.

Unless I misunderstood you, I think there are a few ways you can do this. The easiest that come to mind is to add a component to the root layout. The component will have a mount at which point you can generate the changeset. And as it is a component, you can put the appropriate js, etc. to handle the modal display.

live "/", BlaLive, layout: {Bla.LayoutView, "live_app.html"}

You can also embed the component in a sub-template I think.

The component would have to be stateful so it can handle its own events.