site

personal website, served at mordaunt.dev/site
Log | Files | Refs

hugo-svg-tricks.md (2226B)


      1 +++ 
      2 draft = false
      3 date = 2025-07-16T12:08:03-03:00
      4 title = "Hugo SVG Tricks"
      5 description = "Styling SVG icons alongside font-awesome icons."
      6 slug = ""
      7 authors = ["Jack Mordaunt"]
      8 tags = ["hugo", "svg", "css"]
      9 categories = ["development"]
     10 externalLink = ""
     11 series = []
     12 +++
     13 
     14 ## Configuration driven, dynamic SVG icons
     15 
     16 Change the theme to see the effect.
     17 
     18 {{< inline-svg name="self-tiny-white" >}}
     19 
     20 TLDR; 
     21 
     22 - inline the SVG content directly into the HTML (avoid `<img>` tags, they disable CSS)
     23 - use `{{ readFile "assets/images/image.svg" | safeHTML }}` to load it from a file at build time
     24 - that path can be driven from configuration
     25 - ensure the SVG has width and height set to `100%` to allow CSS to scale them
     26 - place the SVG under `assets` for Hugo to use in pipelines
     27 
     28 SVG images are troublesome. They're ubiquitous and yet riddled with quirks. 
     29 
     30 The goal: add a configuration driven (not static) SVG icon to fit alongside font-awesome icons, that can be styled with CSS. For example a favicon that changes colour based on the theme. 
     31 
     32 Font Awesome doesn't include every possible icon, just common ones. It bakes those icons into a font and refers to theme via unicode code points. This is great for compactness and ease of use when the icon is available within the font, but doesn't translate well to third-party SVG icons. 
     33 
     34 In addition, there's a stark difference between inlining an SVG via `<svg>` tags, or referencing the image via an `<img>` tag. The former can be styled by CSS, the latter cannot. This means you must acquire the real SVG image and prepare it to be inlined. Thankfully you can apply CSS to the SVG as a normal tag once inlined.
     35 
     36 If all you need is a singular SVG, then you can copy it into your HTML and stop here. 
     37 
     38 To drive these icons from configuration you can configure the path to the SVG file like so:
     39 
     40 ```toml
     41 [[params.social]]
     42   name = "Sourcehut"
     43   svg = "assets/images/sourcehut.svg"
     44   url = "https://git.sr.ht/~jackmordaunt"
     45 ```
     46 
     47 In your template you can then embed the SVG as follows: 
     48 
     49 ```html
     50 <div>{{ readFile .svg | safeHTML }</div>
     51 ```
     52 
     53 And you can style it as you like:
     54 
     55 ```html
     56 <div style="fill: #000; transition: fill 0.5s ease-in;">{{ readFile .svg | safeHTML }}</div>
     57 ```
     58