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!
Leave A Comment
Using mypartial.css (i.e. name your partial with *.css suffix) is a better solution.
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.
Please correct me if Im wrong but it doesn’t seem to work with css within a theme, it shows me an error “cannot find file…”
I haven’t tested this, but it should work the same way. You just need to update the file path to point to your themes
static/
directory instead of the root Hugo one.