Cannot insert literal HTML because & is always escaped
paulinemss opened this issue · comments
Hi,
An issue came up with HTML content that we receive from the server. We want to insert it into htm
without escaping it. According to #137, we should be able to do as follows:
import htm from "htm";
import vhtml from "vhtml";
const html = htm.bind(vhtml);
const frag = "<p>Hello, World!</p>"
console.log(html`<div>${html([frag])}</div>`); // output: "<div><p>Hello, World!</p></div>"
However, this doesn't work with HTML special characters - see example below (and in CodeSandbox).
It looks like html([])
is still escaping &
to &
, which breaks other special chars.
import htm from "htm";
import vhtml from "vhtml";
const html = htm.bind(vhtml);
const frag = "<p>Hello < World</p>" // "Hello < World"
console.log(html`<div>${html([frag])}</div>`); // output: "<div><p>Hello &lt; World</p></div>"
Could this be a bug? Or is above not the intended use case for inserting literal HTML? Is this perhaps not supported at all?
As an example use case, we might be getting highlighted search results (I <3 <em>htm</em>
) from the trusted server, which we want to insert into a htm
template without escaping.
Hi @paulinemss!
This is a vhtml thing fwiw, not HTM. That said, you're close to the right solution! html() doesn't support bypassing sanitization of nested calls (I don't recall the reason). It does support the dangerouslySetInnerHTML
prop similar to React though, which does what you're looking for:
const frag = "<p>We <3 <em>htm</em></p>";
const rendered = html`<div dangerouslySetInnerHTML=${{ __html: frag }}></div>`;
Thanks a lot @developit!