markmark206

markmark206

HEEX formatter (Phoenix.LiveView.HTMLFormatter / mix format) seems to introduce an unexpected line break in the generated html. User error? A bug? ; )

This looks super-related to Formatter adds space/newline to inline elements · Issue #2237 · phoenixframework/phoenix_live_view · GitHub, but, AFAICT, the fix got merged in LiveView 0.18.2, and I am seeing the problem in 0.18.3.

Details:

Here is my repro (happy to provide a more streamline repro gist, if useful):

I want to add a comma after some text

        <%= link to: ... do %>
          <%= @item.content %><% end %>,

and this works great. Here is the web page (loaded in Safari, on a Mac):
image

Running mix format, moves the <% end %> element (and, therefore, the comma that follows) to its own line:

        <%= link to: ... do %>
          <%= @item.content %>
        <% end %>,

which introduces a space before the comma:
image

I am not expecting a code formatter to change what the code does, only what the code looks like. Am I doing something obviously silly here, or does this look like a bug? ; )

Thank you!

PS A bit more data:

$ cat .formatter.exs
[
  line_length: 120,
  import_deps: [:ecto, :phoenix],
  plugins: [Phoenix.LiveView.HTMLFormatter],
  inputs: ["*.{heex,ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{heex,ex,exs}"],
  subdirectories: ["priv/*/migrations"]
]
$ cat mix.exs | grep phoenix
      {:phoenix, "~> 1.6"},
      {:phoenix_ecto, "~> 4.4"},
      {:phoenix_html, "~> 3.2"},
      {:phoenix_live_dashboard, "~> 0.7"},
      {:phoenix_live_reload, "~> 1.4", only: :dev},
      {:phoenix_live_view, "~> 0.18.3"},
$ elixir --version
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit] [dtrace]

Elixir 1.14.1 (compiled with Erlang/OTP 25)

Showing Posts 1 to 9

BartOtten

BartOtten

I guess this has to do with how how HTML is specced. Browsers condense multiple whitespace characters (including newlines) to a single space for most scripts (Latin for example).

Can you show us the generated HTML source? Won’t be surprised when it looks like

<a href=“http://foo.com”>content</a>
,

or

<a href=“http://foo.com”>
   content
</a>
,

W3C about whitespace

However…as this is code and not HTML I guess the formatter should recognize such and this is a bug.

zachallaun

zachallaun

In the meantime, you could do:

<%= link to: ... do %>
  <%= "#{@item.content}," %>
<% end %>
markmark206

markmark206 OP

Sure, here is what the html looks like in both cases:

$ elixir heexformat.exs
next_line: "<a href=\"/i\">\n  next line\n</a>,\n" <<<<< notice \n just before the closing </a> and ","
same_line: "<a href=\"/i\">\n  same line</a>,\n"

, where heexformat.exs is

Mix.install(
  [
    {:jason, "~> 1.4"},
    {:phoenix, "~> 1.6"},
    {:phoenix_live_view, "~> 0.18.3"}
  ],
  config: [
    phoenix: [json_library: Jason]
  ]
)

defmodule HeexFormatTest do
  use Phoenix.HTML
  import Phoenix.Component, only: [sigil_H: 2]

  def to_text(h) do
    h
    |> Phoenix.HTML.Safe.to_iodata()
    |> List.to_string()
  end

  def generate_html_next_line() do
    assigns = %{}

    ~H"""
    <%= link to: "/i", method: :get do %>
      <%= "next line" %>
    <% end %>,
    """
  end

  def generate_html_same_line() do
    assigns = %{}

    ~H"""
    <%= link to: "/i", method: :get do %>
      <%= "same line" %><% end %>,
    """
  end
end

HeexFormatTest.generate_html_next_line() |> HeexFormatTest.to_text() |> IO.inspect(label: :next_line)
HeexFormatTest.generate_html_same_line() |> HeexFormatTest.to_text() |> IO.inspect(label: :same_line)
adamu

adamu

Does anyone know how to deal with this?

For example, if I write

<a href="/foo">Foo</a>

Formatting it can result in

<a href="/foo">Foo </a>

Adding a space and changing the appearance.

This happens whether I use <a> or <.link>.

LostKobrakai

LostKobrakai

Your example formats just fine for me. But you can also use this: Phoenix.LiveView.HTMLFormatter — Phoenix LiveView v1.0.9

adamu

adamu

Sorry, I simplied it. I’ll check out the LiveView formatter, thanks.

Here’s a reproducible example:

<div>
  <div>
    <div>
      <div>
        <div>
          <div>
            <div>
              <a
                class="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                href="/foo"
              >Foo</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

frankdugan3

frankdugan3

Did you look at the link he posted? The documentation describes a phx-no-format attribute you can add to any element to disable formatting for that element. So in your case:

<a
  phx-no-format
  class="..."
adamu

adamu

Yes I did, and that avoids the problem. But I agree with @markmark206 - it’s surprising that the formatter adds whitespace to visible text where there was previously none. So it’s really a workaround, rather than a solution.

Out of curiosity, I checked what Prettier does, and it formats it as the following, which preserves the visible whitespace.

<a
  class="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  href="/foo"
  >Foo</a
>
— All posts loaded —

Where Next? Top

Trending in Discussions Top

cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
achempion
I’ve been using Emacs as my main code editor for more than a two years. It’s a custom build version although I’ve tried doom emacs and sp...
New
axelson
Hi there! :wave: @frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
georgeguimaraes
Just published claude-code-elixir, a plugin marketplace for Claude Code with Elixir support. These are the plugins I’ve been using for my...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews