HEEX syntax error with some SVG, but LEEX is being deprecated. Where do I go?

I’m starting to convert an app to Phoenix 1.6 and LiveView 0.16. In it, I have a component that renders some SVG and uses LiveView to update e.g. a <polygon>'s points at a high rate of speed. It would be great to use HEEX templates and keep up to date, since LEEX is apparently deprecated, and I like the function component syntax.

The problem I’m bumping into is that the HEEX engine only really knows about HTML, and considers camelCase SVG tags like <linearGradient> to be a syntax error.

My component is defined roughly like this:

defmodule Open890Web.Live.BandScopeComponent
  use Open890Web, :live_component

  def render(assigns) do
    ~L"""
      <div class="bandscope">
        <svg>
          ...
          <defs>
            <linearGradient id="myGradient" gradientUnits="userSpaceOnUse">
             ...
            </linearGradient>
          </defs>
          <polygon id="bandSpectrum" class="spectrum" points={scope_data_to_svg(@band_scope_data} vector-effect="non-scaling-stroke" />
        </svg>
     </div>
    """
  end
end

This results in the error: expected tag name containing only lowercase chars, got: linearGradient

So, I realize that SVG is not technically HTML, but being able to generate SVG in my LEEX template was nice because it just worked. What are my options moving forward? This component doesn’t handle any events like phx-click. Should I just be rendering a .html.eex file instead?

1 Like

I can look into this on the engine side, but you can simply lowercase the g, no?

3 Likes

You know, that totally worked. I had some other code removed that made me think the browser wasn’t accepting it, but I went back over it all a little more carefully, and Firefox and Chrome both accept the SVG that way. Thanks!

1 Like

This was interesting to me so I googled a bit and I think this is issue is relevant to what was discussed SVG element names should not mix camelCase and lowercase notations · Issue #161 · w3c/svgwg · GitHub
From there

The HTML parser automatically corrects all case errors. So you can use whichever case you want, and it will convert it to the canonical version as it parses. However, DOM methods for scripting are all case sensitive, as is the XML parser used by stand-alone SVG files. So we do need to define canonical casing, and we can’t change existing casing without breaking backwards compatibility for scripts.

Yeah, fortunately FF/Chrome don’t actually complain about the lowercase elements. If it was indeed going to be a problem, I was thinking maybe the HTML engine could relax the rules for elements with e.g. an xmlns attribute that wasn’t HTML, but that’s all a moot point now.

My spectrum scope is working again, and I’ve got components, so I’m a happy camper :slight_smile:

10 Likes

I understood from that issue I linked that it’s ok to keep them lowercase in HTML, so as <lineargradient>. I don’t know what they mean by DOM methods being all case sensitive and if it effects morphdom that LiveView uses. Maybe @chrismccord can shine light on that subject.

Agreed. We’ll relax the rules allowing camelcase nodes :+1:

3 Likes

Nice. It certainly would help readability!

I had some other code removed that made me think the browser wasn’t accepting it

If I had to finger a culprit, I’d put all of my money down on React/JSX

Nah, no React/JSX involved, only my own stupidity :upside_down_face:

1 Like

For anyone else currently running into this problem, fixed in Relax html tag validation by msaraiva · Pull Request #1615 · phoenixframework/phoenix_live_view (github.com)

Should be live on v0.16.4.

Hats off to everyone in the dev team. :confetti_ball:

7 Likes

That’s a beautiful UI, and in the Edward Tufte sense too!

2 Likes

nooo, my life savings ;_;

Looks like you’re building something really cool!

Thanks for the kind words – perhaps one of these days I’ll write a post about it, with some video clips or something!

2 Likes

I’d really like to read/see that! Would you mind writing about it in a Q&A post on this forum? It looks like you have a really nice way to make dynamic, and soft real time (?), visualizations, which is really handy for lots of things!

1 Like

I posted a thread here: Open890: A web-based ham radio UI built with Phoenix LiveView

3 Likes

I am experiencing this same weird error with a for loop inside a script in my heex template.

    <script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/app.js")}></script>
    <script defer type="text/javascript">
      for (let i = 0; i < 10; i++) {
        console.log(i);
      }
    </script>

I’m not sure what tag it’s expecting and I’ve been combing through the hexdocs for a few hours.

= Compilation error in file lib/gaming_web/views/layout_view.ex ==
** (Phoenix.LiveView.HTMLTokenizer.ParseError) lib/gaming_web/templates/layout/root.html.heex:13:26: expected tag name
(phoenix_live_view 0.16.3) lib/phoenix_live_view/html_tokenizer.ex:137: Phoenix.LiveView.HTMLTokenizer.handle_tag_open/5
(phoenix_live_view 0.16.3) lib/phoenix_live_view/html_engine.ex:89: Phoenix.LiveView.HTMLEngine.handle_text/3

It’s probably not too happy with the in-line JS, but it’s hard to say. It’s usually better to not have inline, but I could see the argument that the engine shouldn’t ignore everything inside a script tag if that is indeed the problem.