I'm trying to parse a SVG element from a string and render it into the DOM but when I parse as image/svg+xml
, the <svg>
gets appended into the DOM in some strange way that does not render it (at least in Firefox). When I parse as text/html
, it does render but adds an undesired xmlns
attribute.
Is there some way to still parse as image/svg+xml
(because that's what it is) while having it render? I tried document.adoptNode but it did not help.
This does not render:
const svg = '<svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 1 1 0 1.5H8.5v4.25a.75.75 0 1 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2z"/></svg>';
const parser = new DOMParser();
const doc = parser.parseFromString(svg, 'image/svg+xml');
document.body.appendChild(doc.documentElement);
This renders, but includes undesired xmlns
attribute:
const svg = '<svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.75 2a.75.75 0 0 1 .75.75V7h4.25a.75.75 0 1 1 0 1.5H8.5v4.25a.75.75 0 1 1-1.5 0V8.5H2.75a.75.75 0 0 1 0-1.5H7V2.75A.75.75 0 0 1 7.75 2z"/></svg>';
const parser = new DOMParser();
const doc = parser.parseFromString(svg, 'text/html');
document.body.appendChild(doc.body.firstChild);
The DOMParser()
interface has a method parseFromString(string, mimeType)
which parses a string containing either HTML or XML & returns an HTMLDocument or an XMLDocument.
The second parameter mimeType
determines whether to use XML parser
or the HTML parser
. Only text/html
will invoke the HTML parser, and any other valid MIME type will invoke the XML parser refer
So, it will work as :
const svg = '<svg height="100" width="100" xmlns="http://www.w3.org/2000/svg"><circle r="45" cx="50" cy="50" fill="grey" /></svg> ';
const parser = new DOMParser();
const doc = parser.parseFromString(svg, 'image/svg+xml');
const svgImg = doc.querySelector("svg")
document.body.appendChild(svgImg);
<html>
<body>
<h2>Parsing SVG using DOMParser()</h2>
</body>
</html>