Set innerHTML of an element in Svelte


When working on a Svelte application, I wanted to replace newline characters in a string with <br> elements and render the result as HTML. If you do the replace in your component markup, then the rendered output has escaped angle brackets:

<!-- Component.svelte -->
<p>{notes.replace(/\n/g, '<br>')}</p>

<!-- Output markup -->
<p>Line one&lt;br&gt;Line two</p>

From previous experience, I know that we’re not rendering the replaced string as HTML, so I tried searching online for a solution involving innerHTML.

In the Svelte API docs, there are only three mentions of innerHTML, two of which refer to bindings with contenteditable elements. But I wanted to set the innerHTML of an element that would never change.

While searching through the Svelte Discord for innerHTML, I came across an unrelated post that mentioned {@html}. I had never encountered this before, so I looked it up in the Svelte docs[1]:

In a text expression, characters like < and > are escaped; however, with HTML expressions, they’re not.

Not the longest explanation, but that sounds like my problem. Back in my code, I tried wrapping the replaced text with {@html}:

<!-- Component.svelte -->
<p>
{@html notes.replace(/\n/g, '<br>')}
<p>

With that, everything rendered as expected:

<!-- Output markup -->
<p>
Line one<br>
Line two
</p>

So next time you want to set the innerHTML of an element in Svelte, use an HTML express with {@html}.

Happy escaping!


Footnotes

  1. https://svelte.dev/docs#html ↩︎

About

My name is Sean McPherson (SeanMcP), and I am a software engineer based in Pittsburgh, PA. Here I write articles about programming for developers of all levels.