Add SVG icons to your Hugo site

Start using hugo-mod-icons — an icon module that scales.

…mug not available separately

Let’s use SVG icons

When I developed my first Hugo theme more than four years ago (already), I was searching for a reliable option to embed SVG icons as an alternative to icon fonts, but only for the icons that the users of the theme actually needed.

  1. Missing browser support: Back then in 2017, SVG icon browser support (and their more advanced features) was not good. This forced me to fallback to an icon font approach where I needed to polyfill multiple older browsers, and things always become more messy when you have to provide all kinds of backward-compatibility. It’s not only holding you back from some good features, but especially from a good performance, and I’m a big fan of performant websites.
    It’s 2021 now and a lot of things have changed in the browser landscape, be it positive or negative. One of the positive things is the great browser support for SVG icons.
  2. Website size: The relatively simple approach of inlining SVG icons makes it possible to only embed the icons that are wanted, but embedding one and the same icon n times leads to an increase of n times the size of the SVG icon. The same holds true for information such as SVG’s <title> or <desc> tags which help accessibility, which is not really cool and defeats the purpose of DRY.


I developed the module with the goal to make it extra user-friendly and scalable, just like SVGs themselves. Here is a summary of the most important features:

  • Currently supports Font Awesome, but aims to be icon-family agnostic in future
  • User-friendly partial API with support for various usage patterns, including custom icon name support
  • Carefully implemented and structured partials, fully utilizing Hugo’s capabilities (read more below)
  • Smart and comfortable icon search function
  • Auto-enabled accessibility by considering icon’s metadata

Implementation: A Composition of Partials

I implemented hugo-mod-icons via multiple partials which form the building blocks of the module. If you have a programming background, you can compare each partial with a function that has predefined input parameters and returns an output value. Just like in OOP, I divided the partials between the documented “public API” (e.g. icon-partial) and more private partials (e.g.icon-search and icon-resolve) which are used internally by the public partials.

Architecture to resolve and search for best matching icons (overview, does not show all involved partials)
Warning when using the search feature to ensure forward compatibility

Passionate Software Engineer and Maker ◦