DEV Community

loading...
Cover image for IE adds double XMLNS on SVG markup when converting to string
Team ORNIO

IE adds double XMLNS on SVG markup when converting to string

Flamur Mavraj
CEO & Founder @ Ornio AS and CTO & Co-Founder @ uWork AS. I help businesses grow and transform using technology.
Updated on ・3 min read

We where tasked/needed to serialize SVG files on a project we are working on, and while the first implementation worked well on most (normal) browsers, it did not take too long time before we got some complains that our images where not being displayed properly.

After some debugging we found out that all these cases where related to users using IE. And after dusting of my Windows laptop and started testing we could reproduce the issue ❤️ (as developer I get a relief when I can reproduce an bug)

After a quick search on Google for IE svg adding double xmlns following two links helped understanding the issue and led to a fix:

First implementation (Does NOT work on IE)

We do use Figma to design and create our SVG's, when exporting, the SVG contains the xmlns-tag by default.

Here is an SVG example showing a red circle where the xmlns-tag is already set:

<svg height="100" width="100" xmlns="http://www.w3.org/2000/svg">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="1" fill="red" />
</svg> 
Enter fullscreen mode Exit fullscreen mode

The serialize function we used is straight forward using XMLSerializer:

export const svgSerialize = (el: SVGSVGElement) => new XMLSerializer().serializeToString(el);
Enter fullscreen mode Exit fullscreen mode

This will result in following result:

<svg height="100" width="100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="1" fill="red"/></svg>
Enter fullscreen mode Exit fullscreen mode

And as said this worked perfectly on all other browsers expect Internet Explorer. Here is the result of same image on IE:

<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="1" fill="red"/></svg>
Enter fullscreen mode Exit fullscreen mode

Yes you spotted right, yet another xmlns="http://www.w3.org/2000/svg"-tag has been added to the SVG :(

Browsers are strict on XML parsing and therefor the above image will not be displayed!

After some trial and errors here is how we fixed the issue.

The solution

First we removed xmlns tag from our SVG:

<svg height="100" width="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="1" fill="red" />
</svg> 
Enter fullscreen mode Exit fullscreen mode

And our new svgImageToString function looks like this:

export const svgImageToString = (el: SVGSVGElement) => {
    // Serialize the SVG object, this will add an xmlns on IE
    const serialized = new XMLSerializer().serializeToString(el);

    // We then do convert back the SVG serialized string to new SVG 
    const parser = new DOMParser();
    const newSvg = parser.parseFromString(serialized, "image/svg+xml");
    const newSvgEl = newSvg.firstChild as SVGSVGElement;

    // We check if the new SVG has xmlns if not we added to it
    if(!newSvgEl.hasAttribute('xmlns')){
        newSvgEl.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
    }

    // We serialize the new element again and return the result
    return new XMLSerializer().serializeToString(newSvgEl)
}
Enter fullscreen mode Exit fullscreen mode

You are probably thinking why converting the SVG serialized string back to SVG object using DOMParser, due to our complex SVG's we where not able to detect and remove the double xmlns-tag in another way (yes we tried with regex).

Hope this will help others that will face this issue 😊

Comment if you have other alternatives to the solution!

Cheers :)

Discussion (0)