In one of our projects we wanted to use SVG icons instead of font icons due to better scalability, quality and less complexity when adding new icons.
Quite early in the process we noticed that the icons did´nt work in Internet Explorer.
After some investigation we made the conclusion that it is not allowed to access a SVG icon with the full path like icon.svg#icon-id in Internet Explorer. Instead we needed to access it by the id directly, without filename, and put the source of the SVG file in the DOM so that the ID for all icons exists in the DOM.
To get this to work as smooth as possible we made a Html Helper to render the icon markup and a Html Helper to render the SVG source in the DOM if the visitor is using Internet Explorer.
The SVG source object has the CSS class srt to be hidden in the UI.
We also added cache for the SVG file to not load if from IO all the time.
You will find a sample of the code below for inspiration.
using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using Castle.Components.DictionaryAdapter.Xml;
using EPiServer.Framework.Cache;
using EPiServer.Licensing.Services;
using EPiServer.ServiceLocation;
using Customer.Web.EPiServerExtensions.Rendering;
namespace Customer.Web.EPiServerExtensions.HtmlHelpers
{
public static class SvgIconHelper
{
public static IHtmlString SvgIcon(this HtmlHelper helper, string icon, string cssModifier = null)
{
var buffer = new StringBuilder();
var writer = new StringWriter(buffer);
var browserName = helper.ViewContext.HttpContext.Request.Browser.Browser;
var path = (browserName == "InternetExplorer" ? "" : Fingerprint.Tag($"/Assets/shared/img/icons.svg"));
writer.WriteLine($"<svg class=\"icon {cssModifier}\" aria-hidden=\"true\"><use xlink:href=\"{path}#{icon}\"></use></svg>");
return new MvcHtmlString(buffer.ToString());
}
public static IHtmlString LoadIconSet(this HtmlHelper helper, string path)
{
var cacheInstance = ServiceLocator.Current.GetInstance<IObjectInstanceCache>();
var cacheKey = "svgicons" + path;
var iconFileInCache = cacheInstance.Get(cacheKey) as string;
if (iconFileInCache == null)
{
var fullPath = HttpContext.Current.Server.MapPath(path);
XDocument doc = XDocument.Load(fullPath);
var node = doc.Root;
node.SetAttributeValue("class", "srt");
iconFileInCache = node.ToString();
cacheInstance.Insert(cacheKey, iconFileInCache, new CacheEvictionPolicy(new TimeSpan(365, 0, 0, 0), CacheTimeoutType.Absolute)); //cache for 365 days
}
var buffer = new StringBuilder();
var writer = new StringWriter(buffer);
writer.WriteLine(iconFileInCache);
return new MvcHtmlString(buffer.ToString());
}
}
}
Leave a Reply