Hugo Quick Tip: Inlining CSS Files

Posted by on . Last Updated on . Tagged:hugo

Today I have been doing a little bit of work on my site and one of the things that I wanted to do is inline the css file. It’s quite a small file anyway, and once compressed with gzip should make a fairly minimal difference to the size of the page.

The readFile function

In Hugo, the readFile function looks for a file relative to the current project working directory and returns it as a string. If we had a file located at: <root>/static/css/site.css, then we could render the file out like so:

<style>{{- renderFile "/static/css/site.css" -}}</style>

NB: Remember to close the squiggly brackets so that Hugo renders it correctly.

There is a gotcha with this approach so far. Hugo will try and do its thing with the resultant string and what you will end up with is something along the lines of:

<script>ZgotmplZ</script>

as opposed to your intented css contents. Luckily, there is a piped method that we can use to sort this out for us:

<style>{{- renderFile "css/site.css" | safeCss -}}</style>

Reading a hashed file

As you may recall in my previous Hugo post, I setup my css files with cache busting capabilites by appending the hash onto the filename. In order to render this as part of the HTML, we need a few things:

  • Find the name of the hashed file
  • Build the file path
  • Call readFile

In order to get the hashed file name, we can inspect the site’s data sources, looking for the file name (requires post mentioned above):

{{ $siteCssHash := (index .Site.Data.hash "site.css") }}

Next, we need to build up the correct file path. Note, this is the file path prior to rendering:

{{ $siteCssPath := (printf "/static/css/%s" $siteCssHash) }}

Finally, we need to call readFile and ensure that it is marked as a safe css string:

<style>{{- readFile $siteCssPath | safeCSS -}}</style>

So putting the three together:

{{ $siteCssHash := (index .Site.Data.hash "site.css") }}
{{ $siteCssPath := (printf "/static/css/%s" $siteCssHash) }}
<style>{{- readFile $siteCssPath | safeCSS -}}</style>

And that’s it. When the page reloads/is rebuilt, your pages should now contain inlined css.

Stuart Blackler is a seasoned technologist with over 15 years of commercial experience in the .NET ecosystem. Holding a degree in Computer Science, Stuart has earned certifications as a C# developer through Microsoft and as an AWS Solutions Architect and Developer. Stuart is the creator of the popular YouTube channel CodeWithStu, where he delves into topics close to his heart, including .NET, AWS, DevOps, and software architecture with a commitment to sharing knowledge and fostering a community of learners.