Create a gist now

Instantly share code, notes, and snippets.

Fixes references to inline SVG elements when the <base> tag is in use.
/**
* SVG Fixer
*
* Fixes references to inline SVG elements when the <base> tag is in use.
* Firefox won't display SVG icons referenced with
* `<svg><use xlink:href="#id-of-icon-def"></use></svg>` when the <base> tag is on the page.
*
* More info:
* - http://stackoverflow.com/a/18265336/796152
* - http://www.w3.org/TR/SVG/linking.html
*
* One would think that setting the `xml:base` attribute fixes things,
* but that is being removed from the platform: https://code.google.com/p/chromium/issues/detail?id=341854
*/
(function(document, window) {
"use strict";
/**
* Initialize the SVG Fixer after the DOM is ready
*/
document.addEventListener("DOMContentLoaded", function() {
/**
* Current URL, without the hash
*/
var baseUrl = window.location.href
.replace(window.location.hash, "");
/**
* Find all `use` elements with a namespaced `href` attribute, e.g.
* <use xlink:href="#some-id"></use>
*
* See: http://stackoverflow.com/a/23047888/796152
*/
[].slice.call(document.querySelectorAll("use[*|href]"))
/**
* Filter out all elements whose namespaced `href` attribute doesn't
* start with `#` (i.e. all non-relative IRI's)
*
* Note: we're assuming the `xlink` prefix for the XLink namespace!
*/
.filter(function(element) {
return (element.getAttribute("xlink:href").indexOf("#") === 0);
})
/**
* Prepend `window.location` to the namespaced `href` attribute value,
* in order to make it an absolute IRI
*
* Note: we're assuming the `xlink` prefix for the XLink namespace!
*/
.forEach(function(element) {
element.setAttribute("xlink:href", baseUrl + element.getAttribute("xlink:href"));
});
}, false);
}(document, window));
@ianpetzer

Thanks... This helped me to get my svgs working on Firefox

@GuillaumeG22

Thanks for this polyfill !

@jbouzekri

Same here. Many thanks !!!!

@saadshahd

Thanks a lot ❤️ ❤️ ❤️

@Klenkes
Klenkes commented Feb 19, 2016

Huge thanks from me too!
Since I am male no red hearts but both thumbs up, a long and happy life, and again many thanks for saving my day.

@w8r
w8r commented Apr 7, 2016

@leonderijke, thank you big time! if only I could get the time back I wasted finding out what causes that in a huge app))

@havarnov

As far as I can tell this is an issue in Chrome as well.

@felixpfeiffer

Thanx for that. You saved my life!

@gera2ld
gera2ld commented May 17, 2016

This is great! But still has problem in Chrome.

@p-hebert

You good sir, have just saved me from seeing a 70+ hour plugin fail miserably because its icons wouldn't show.
Long life to you.

@lastmjs
lastmjs commented Aug 24, 2016

Thanks a ton! Can we get a license for this?

@adyz
adyz commented Aug 31, 2016

Sometimes I have some # links that I forgot to preventDefault and when I have locations like localhost:3000/# the script does not work properly.

You can add .replace('#', ''); to the baseUrl after replacing hash

@mattiLeBlanc

Great find, it took me a while to figure out the my BASE tag was the culprit.
Tip for people using Angular or React: make a SVG component that does the path replacement on render.
For my angular app, the Domload event would happen before any of the ng-repeated rows would be rendered so the paths would not be replaced. Turning the svg into a component solved that for me since on creation I could replace the path.
cheers

@lnked
lnked commented Feb 7, 2017

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment