Skip to content

Inline CSS with Hugo Static Site Generator

You know the drill, you run your site through one of the many online performance tools, and you’re told to optimise delivery of CSS, and inline critical CSS. This was me a few weeks ago, I’ve been playing around with static site generators, in particular Hugo (which is awesome, you should totally try it), and realised I had no idea how to inline CSS.

Sure, I could do what the internet suggested, and put my css into css.html and load in as a partial, but that just felt wrong, it’s not HTML, it doesn’t belong in an HTML file. I googled again, and again, and again, then gave up and decided to read the docs.

So this is what I ended up with after stumbling across the readFile function. It’s simple, elegant, it’s actually in a CSS file (hurray), and all works well with whatever build tool you prefer to use (in my case Gulp).

<style>{{ readFile "static/critical.css" | safeCSS }}</style>

It’s stored in the static folder, which is cool, it means you can switch to <link rel="stylesheet"> anytime with no real effort. No need to change your build process, just update your template to reference the external stylesheet.

Update: Although fine for small sites, if you’re running a site with thousands of pages, you may want to consider wrapping this in a partial, and caching it. I setup a test with 10,000 dummy posts and benchmarked the build time to create 10,000 HTML files, this took 6 seconds. I then wrapped this call in a partial which was cached and the results were significantly better at 3 seconds.

{{ partialCached "head/styles.html" . }}

The head/styles.html partial contains the example from above, which becomes cached (as the contents of the CSS are always the same):

<style>{{ readFile "static/critical.css" | safeCSS }}</style>

And that is that. Happy to help!

Comments

    1. Christopher Geary

      Christopher Geary

      Partials are stored within /layouts, and CSS is not a layout. Neither is it intuitive for people that are unfamiliar with your project.

      I agree a partial is better for the sole purpose of caching your partial. But the same can be achieved with this approach + a wrapping partial which still keeps things in the most appropriate directory.

Have Your Say

Your email address will not be published. Required fields are marked *