As the title says, I am struggling to make svg icon work in IE11. Here is a simple reproducible version of my problem.
App:
<aura:application >
<c:SVGComponent ariaHidden="true"
class="slds-icon slds-icon-standard-contact slds-icon--small"
xlinkHref="/resource/SLDS0121/assets/icons/standard-sprite/svg/symbols.svg#case">
</c:SVGComponent>
</aura:application>
Component:
<aura:component access="public">
<aura:attribute name="class" type="String"/>
<aura:attribute name="xlinkHref" type="String"/>
<aura:attribute name="ariaHidden" type="String" default="true"/>
</aura:component>
Renderer for the component:
({
render: function(component, helper) {
//grab attributes from the component markup
var classname = component.get("v.class");
var xlinkhref = component.get("v.xlinkHref");
var ariaHidden = component.get("v.ariaHidden");
//return an svg element w/ the attributes
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('class', classname);
svg.setAttribute('aria-hidden', ariaHidden);
svg.innerHTML = '<use xlink:href="'+xlinkhref+'"></use>';
return svg;
}
})
When accessing the app in google chrome, icon displays fine but in IE 11 nothing shows.
Upon inspecting the network log in IE browser, I noticed that IE is not even downloading the svg file.
Screenshot in chrome(svg icon successfully displayed):
I tried the solutions mentioned in the following similar questions but no success, So please don't close as duplicate.
Best Answer
This is not a Lightning issue, but a browser compatibility issue. IE 9-11 does not support external resources for svgs (e.g. the
use
tag with anxlink:href
), so writing this inline is the best option. There are some really nasty hacks available online, such as https://github.com/jonathantneal/svg4everybody, but I would not recommend use of this library. If you do use it, please refactor it to address the XSS issues below, be sure to hook it into a renderer, and you'll have to find some creative solution on your to this running outside the framework's lifecycle. E.g. the framework is going to think that your image is fully rendered as soon as you make the callout, when it won't actually be on the page yet. Also, I don't know if this approach is guaranteed to work in future versions of Lightning because of how it uses xhrs, and really putting the SVG data inline yourself is going to be much easier and faster that initiating an async xhr call to pull the data from static resources and then re-writing the document to put the data in-line in an unsafe way.For other browsers, please try to avoid the use of
innerHTML
with string attributes as they become an XSS sink. You don't needinnerHTML
here, you can build up the element with DOM accessors, such ascreateElement()
,setAttribute()
, andappendChild()
. That avoids possible ambiguities in html parsing of strings, particularly as you don't have any native JS and html encoding libraries available to you in Lightning.href
is an XSS sink because of javascript pseudo-schemes (xlink:href="javascript:payload"
will cause the payload to execute), so please verify that what goes intohref
starts with'https://'
if it is an absolute URL or"/"
if it is a relative URL. This is true fora href
as well as other attributes such asframe src=""
. For a more complete list of unsafe attributes (there are many), look here: https://html5sec.org/