SASS Processing with Hugo Pipes

Janne Kemppainen |

So far we have been using the CDN version of Bulma. However, this has the unfortunate property that we cannot really customize the colors and other parameters. We can solve this by using Hugo pipes to process the Bulma source code with the built-in SASS processor.

Note that you need to have the Hugo extended version for SASS/SCSS processing.

There are only three steps that you need to go through to configure a Sass pipeline with Hugo:

  1. write or provide an existing SASS or SCSS file in the assets directory
  2. load the file as a resource and use the Hugo built-in converter to generate CSS
  3. link the generated stylesheet in the page head template.

After the configuration everything happens automatically when you run hugo server or build the site. But let's get to the details!

Processing a Sass framework

I will continue to use Bulma as an example but this will work the same way for every SASS/SCSS framework out there. You could get the source files of your selected framework as a git submodule like I'm doing here, or you could alternatively use npm packages.

To get started, you will need to first create the assets directory inside your theme and then add Bulma as a Git submodule:

>> mkdir themes/bloggeri/assets
>> cd themes/bloggeri/assets
>> git submodule add https://github.com/jgthms/bulma.git
>> git commit -m "add Bulma"

If you're working on your website from another computer you need to remember to initialize the submodule in the repository before you can use it:

>> git submodule init --update

Later on if you need to update to a more recent version of the framework you can update the submodule with this command:

>> git submodule update --remote --merge
>> git commit -m "update submodules"

Then you just need to add these two lines in the layouts/partials/head.html file inside your theme:

{{ $bulma := resources.Get "bulma/bulma.sass" | resources.ToCSS (dict "outputStyle" "compressed") | fingerprint }}
<link rel="stylesheet" href="{{ $bulma.Permalink }}">

Remove the CDN version of Bulma if you still have it there in the <head> section. Nothing should visually change on your page but the CSS will now be served from your own site instead of the CDN.

The first line is rather long and unfortunately the Go template statements can't be split into multiple lines without intermediate variables so make sure to scroll all the way to the right to see what it contains.

What happens here is that Hugo will first fetch a resource file from the assets directory. That file is “piped” to the ToCSS processor which uses the file and a map of options to generate the CSS file. Here I'm passing the outputStyle: compressed which minifies the CSS to save some bandwidth.

The output of the CSS processor is then piped to the fingerprint function which calculates the sha256 hash of the file and includes it in the filename. This is an easy way to implement cache busting for the stylesheet because the filename will change whenever the content changes and as a result possible browser caches will then be invalidated automatically.

Customization

While it's cool to have the CSS come from the preprocessor we haven't actually achieved anything meaningul yet as the site still looks the same. So how can we customize things?

If you take a look at the Bulma customization documentation you'll notice that there are basically two steps you need to do to customize the final CSS:

  1. define variables with customized values in a SCSS file
  2. import Bulma or parts of it

Create a new file called style.scss in the assets directory. It should use the SCSS syntax. Change whichever variables you need, I'm only manipulating the primary color for the sake of brevity.

$primary: #1a535c;
@import "bulma/bulma.sass";

Here I have first set the primary color to a custom value and then imported the Bulma source. But of course this is not enough, we also need to modify the head.html template to include the correct resource! Modify the lines so that they look like this:

{{ $style := resources.Get "style.scss" | resources.ToCSS (dict "outputStyle" "compressed") | fingerprint }}
<link rel="stylesheet" href="{{ $style.Permalink }}">

We fetch style.scss as a resource which internally imports Bulma. All primary color elements on the site have now changed to use this custom color.

image-20200608201157471

You can also move all of your custom CSS from the static directory here after the Bulma import and remove the link from the head.html template. And naturally now you can also reap all the benefits of Sass. You could also reduce the compiled CSS file size by importing only the components that you need from Bulma instead of the whole bulma.sass file.

Enable customization from config.toml

From now on it's quite easy for you to continue customizing the theme. But what if you're providing the theme for someone else and they want to use different parameters?

Hugo has got you covered with resource templates. Add one more tweak to the code in head.html:

{{ $template := resources.Get "style.scss" }}
{{ $style := $template | resources.ExecuteAsTemplate "style.scss" . | resources.ToCSS (dict "outputStyle" "compressed") | fingerprint }}
<link rel="stylesheet" href="{{ $style.Permalink }}">

This just adds a call to the resources.ExecuteAsTemplate function which treats the resource as a Go template file. The function takes three parameters:

  1. the resource file
  2. the output filename, and
  3. the context (current context with dot).

I'm using the same name for the output file as the template file, you can use a different name for the template file if you want. Don't forget the dot because a context is required for the function call.

Now we can use Go templates just as we would with the HTML templates which means that we can tap into the site configurations. Here are two customization examples:

{{ with .Site.Params.primaryColor }}
$primary: {{ . }};
{{ end }}
{{ with .Site.Params.googleFont }}
@import url('https://fonts.googleapis.com/css?family={{ . }}:400,700');
$family-sans-serif: {{ . }}, sans-serif;
{{ end }}

@import "bulma/bulma.sass";

The first piece of code defines a configuration variable primaryColor which is used to set the primary color for Bulma. You could add similar configurations for all the other available colors and variables.

The second example is a bit more interesting. It lets you choose a font from Google Fonts and sets it as the font family of the theme. Maybe you'd like to use the “Metal Mania” font? image-20200608205304454

Here's the corresponding configuration in config.toml:

[params]
    primaryColor = "#1a535c"
    googleFont = "Metal Mania"

With some more tweaking you could add a configuration to enable or disable Bulma features.

Conclusion

As you can see processing SASS with Hugo is actually quite simple, and the best part is that you don't even need to install any separate software if you're using the extended version. The templating support makes this even more versatile and opens up lots of configuration options for your theme.

If you have implemented some cool styling features with Hugo pipes I would very much like to hear about them! Share your thoughts on Twitter and we'll see again on the next post.

Discuss on Twitter

Subscribe to my newsletter

What's new with PäksTech? Subscribe to receive occasional emails where I will sum up stuff that has happened at the blog and what may be coming next.

powered by TinyLetter | Privacy Policy