When I use dangerouslySetInnerHTML to render svg it works everywhere except EDGE.
I've created repo with the bug demo: https://github.com/kossnocorp/preact-bug-edge-svg/commit/4d89779717320f1073ba63c25fc98cb0c9642fc1

When I inline the SVG it works fine:

Hiya - looking into this. Here's the repro as a jsfiddle. https://jsfiddle.net/developit/L0pp3yp2/
I took a deep-ish look into this and my first observations are:
innerHTML demo with the same SVG fails just like preact does.<svg child node>.namespaceURI is "http://www.w3.org/1999/xhtml" on a "normal" (in HTML embedded) SVG the child nodes have the correct namespaceURI "http://www.w3.org/2000/svg".So it looks like innerHTML doesn't set the correct namespace and therefore EDGE treats it like custom elements.
Possible solutions:
javascript
const temp = document.createElement('div');
temp.innerHTML =`<svg xmlns="http://www.w3.org/2000/svg">${value}</svg>`;
for (const key in temp.firstChild.childNodes) {
node.appendChild(temp.firstChild.childNodes[key]);
}
creating the svg in a temporary container, move it over and then set possible other attributes:
const temp = document.createElement('div');
temp.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg">${value}</svg>`;
node.parentNode.replaceChild(temp.firstChild, node);
// TODO. Copy over (possibly already set attributes)
Don't fix the issue and leave a hint in the documentation for developers to use the vnode representation of an svg to render it to the dom.
Disclaimer:
I haven't "really" worked with preact until now and thought this would be a complex enough "bug" to learn something about it, so I can't decide what would be the "right" decission to make. I probably would leave it as it is and add a hint to the docs.
I haven't performance or memory leak tested the "solutions" above. But I would test them if you make a decission that this is worth fixing.
Also I'm sorry for misstakes i've made while writing this comment. English isn't my mother tongue and I regularly make misstakes when writing it.
Some googling reveals that older versions of IE do have their fair share of troubles with innerHTML and svg. I don't think it's something we need to fix in Preact, but I'm happy to be convinced otherwise. The most common approach to use svgs that I've come across is to declare them straight up in jsx instead of inserting them via dangerouslySetInnerHTML :+1:
Most helpful comment
I took a deep-ish look into this and my first observations are:
innerHTMLdemo with the same SVG fails just like preact does.<svg child node>.namespaceURIis"http://www.w3.org/1999/xhtml"on a "normal" (in HTML embedded) SVG the child nodes have the correctnamespaceURI"http://www.w3.org/2000/svg".So it looks like
innerHTMLdoesn't set the correct namespace and therefore EDGE treats it like custom elements.Possible solutions:
javascript const temp = document.createElement('div'); temp.innerHTML =`<svg xmlns="http://www.w3.org/2000/svg">${value}</svg>`; for (const key in temp.firstChild.childNodes) { node.appendChild(temp.firstChild.childNodes[key]); }creating the svg in a temporary container, move it over and then set possible other attributes:
Don't fix the issue and leave a hint in the documentation for developers to use the vnode representation of an svg to render it to the dom.
Disclaimer:
I haven't "really" worked with preact until now and thought this would be a complex enough "bug" to learn something about it, so I can't decide what would be the "right" decission to make. I probably would leave it as it is and add a hint to the docs.
I haven't performance or memory leak tested the "solutions" above. But I would test them if you make a decission that this is worth fixing.
Also I'm sorry for misstakes i've made while writing this comment. English isn't my mother tongue and I regularly make misstakes when writing it.