What could be causing the empty `info` and `error` flash messages from `live.html.heex` to appear on my LiveView page?

I am migrating my website’s index page to a LiveView. After setting the LiveView up, there are always empty info and error flash containers at the beginning of the page.

They reappear even after refreshing the browser. Clicking on the flashes does not close them.

Github repo

# live.html.heex

<main class="container">
  <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 %>
</main>
# router.ex

...

pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, {MyAppWeb.LayoutView, :root}
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug :fetch_current_user
  end

...

scope "/", MyAppWeb do
    pipe_through :browser

    live "/", ListsLive
  end

...

It appears that you have a space character inside of the <p> tag in your rendered html. This causes the alert:empty pseudo-selector in app.css to fail, and it renders a live_flash bar with no content

What versions of Phoenix and LiveView are you using? Are you using the HEEx formatter (Can you run mix.format)?

For a quick-hack solution, you might be able to use

<%= if live_flash(@flash, :info) do %>
  <%= live_flash(@flash, :info) %>
<% end %>

For both :info and :error flash messages

In your live.html.heex

3 Likes

Interesting, I did not notice that space at first.

I have Heex formatter setup. After running mix format, the same behavior occurs.

I’m using :pheonix ~> 1.6.11 and :phoenix_live_view ~> 0.17.11

I have tried it with live view 0.17.5 and had the same behavior.

I have the same problem and it appeared juste after I ran for the first time mix format (with all heex stuff setup) on my new project.

Code before formatting :

<main role="main" class="container mx-auto max-w-4xl px-4 lg:px-0">
  <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 %>
</main>

Visual result : everything normal

Code after formatting :

<main role="main" class="container mx-auto max-w-4xl px-4 lg:px-0">
  <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 %>
</main>

Visual result:

I’ll try to search an solution for that.

Versions
ElixirLS 0.13.0
Elixir 1.14.3
Phoenix 1.6.15
Phoenix Live View 0.18.11

@zgore This issue is documented here, I posted a copy-and-paste answer based on a response in the same thread by Chris McCord.

1 Like

For anyone coming to this thread after Phoenix 1.7 has been released, a new approach to handle this is to add the phx-no-format attribute to the HTML element that you don’t want formatted in a way that changes significant whitespace. So for a default flash setup it’ll look like:

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

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