<use> SVG in Javascript

To use fragmentioner and marginalia on my site, I want to insert SVG icons into the HTML pages. Sounds simple unless you check all the browsers — Chrome and Opera just behave weirdly!

Below is a sample of the SVG markup we would like to insert. It uses the <use>-tag to refer to an external SVG file.

<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
	<use xlink:href="/static/icons/entypo-sprites.svg#feather"></use>

Strangely, this issue only arises if we use an external SVGs in <use>.

Now we want to insert this SVG markup into some container in the page using Javascript. To do this we could directly insert the SVG markup using the innerHTML method or first create a DOM node and insert it using the appendChild method.

Below is the Javascript code used to do this for the demos on in this post.


	HTML = '<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"><use xlink:href="/static/icons/entypo-sprites.svg#feather"></use></svg>';

	SVG = document.createElement('template');

	SVG.innerHTML = HTML;

	button1 = document.querySelector('#demo-button1'),
	button2 = document.querySelector('#demo-button2'),
	button3 = document.querySelector('#demo-button3'),
	button4 = document.querySelector('#demo-button4');

	container1 = document.querySelector('#demo-container1'),
	container2 = document.querySelector('#demo-container2'),
	container3 = document.querySelector('#demo-container3'),
	container4 = document.querySelector('#demo-container4');

	button1.onclick = function(){
		var svg = SVG.content.cloneNode(true).firstElementChild;

	button2.onclick = function(){
		var svg = SVG.content.cloneNode(true).firstElementChild;
		container2.innerHTML += HTML;

	button3.onclick = function(){
		var svg = SVG.content.cloneNode(true).firstElementChild;
		container3.innerHTML += HTML;

	button4.onclick = function(){
		var svg = SVG.content.cloneNode(true).firstElementChild;
		container4.innerHTML += HTML;


Let’s try it out. There are four demos below, where yu can click the button on top to insert the SVG into the container below it. I have styled the SVGs with a grey background and a red outline so we can see the SVG even if it does not render.

First we use the appendChild method.

Inserting SVG using the appendChild method

Turns out Chrome and Opera insert the element but do not actually render the SVG!

Now let’s try the innerHTML method.

Inserting SVG using the innerHTML method

Works in every browser!

Next, just for fun, we insert two copies of the SVG first one using appendChild and then innerHTML.

Inserting two SVGs using the appendChild first and then innerHTML

Again, works in every browser. Both SVGs are displayed.

But, now we insert the two copies first using innerHTML and then appendChild.

Inserting two SVGs using the innerHTML first and then appendChild

Now, Chrome and Opera only render the first one and not the second one! However, if you try it again then, Chrome and Opera render three SVGs but not the fourth one and so on…!

This is very mystifying, and more importantly, very very annoying!

Send me (Learn more)