How to use inline SVGs with Hugo

I started developing websites a couple of years back, and I still remember how slow my first website was! The slowness owed to poor asset optimizations on my end. It turns out that delays of a mere second can result in you losing a great deal of traffic. So I started prioritizing performance during web development and learnt some tricks of the trade as I kept progressing ahead. One of those tricks, not actually, is to use inline SVGs instead of icon fonts.
Hence, in this article, I’ll be showing you a way to considerably improve your website’s performance, using inline SVG icons instead of resourceful, yet bulky icon fonts like Font-Awesome. By the end of this article, you’ll have with yourself a fully-functional and lightweight SVG icon system you piled up yourself and a self-satisfaction after removing one more server dependency from your website.

Why go for inline SVGs?

SVGs have a lot to offer. They’re light and as the name suggests, scalable. Quoting Chris Coyier from his article, using an SVG icon system has the following benefits:

  • Small file sizes that compress well
  • Scales to any size without losing clarity (except very tiny)
  • Looks great on retina displays
  • Design control like interactivity and filters

Apart from these benefits, you can actually pretty easily create your own, minimal, icon set using SVGs which have way less network overhead compared to their font counterpart.
The only drawback associated with SVG icon system is that they’re a bit tedious to use as compared to icon fonts which only require you to define an icon element with a class. This drawback, however, vanishes into thin air when you use a templating software such as Hugo.

<!-- Adding an icon using Font Awesome. -->
<i class="fa fa-address-book" aria-hidden="true"></i>
{{/* Adding an icon using SVG icon system with Hugo. */}}
{{ partial "svg" "address-book" }}

I’ve said that using SVGs directly is tedious. That’s because while developing the website, you have to copy and paste the inner contents of the SVG into the HTML every time you want to insert an icon. It is a bit annoying, at least for me, as compared to merely adding an icon element when using font icon systems.

Creating an SVG icon system in Hugo

The way in which I implement SVG icons in Hugo is as follows:

  • Store all the necessary SVGs inside the /assets/images folder.

    I could go for the /static folder, but I prefer /assets as there’s no need for hosting the SVGs on my website since they will be hardcoded within the website source itself.

  • Embed the SVGs in the templates using a partial, say svg.html.

You can download SVGs from IcoMoon or from Font Awesome itself.

The partial

For embedding SVGs inline, I use a partial at /layouts/partials/svg.html. This partial adds a class attribute to the SVG and returns the modified modified contents as an HTML-friendly text.

{{ $svg := . }}
{{ $class := print $svg "-icon" }}
{{ $match := "<svg (.*)?>(.*)</svg>" }}

{{ $replaceWith := printf `<svg class="%s" ${1}>${2}</svg>` $class }}
{{ return (replaceRE $match $replaceWith (printf "/assets/images/%s.svg" $svg | readFile) | safeHTML) }}

Using this method, if you wanted to style an icon, say address-book, independently, you could simply do so by using the .address-book-icon class in CSS.

Well, that’s it for this article. This website uses the above-specific method, so if you’re curious about the end result, just inspect some of the icons. If you have any doubts or suggestions, feel free to comment them down below.