Minifying a Hugo site with Gitlab CI

Posted May 17, 2018

Last updated February 14, 2022 | aa43e5e

3 minute read

One of the things I love most about Hugo is the tiny size of the pages. Mine in particular uses very little JavaScript, so it loads very quickly and with minimal requests to the servers. Yet, ever since setting up the site, I’ve wanted to be able to make it even smaller.

One of the quirks about Hugo is even if there isn’t anything to render in the partials or layouts for a page, it will still leave a blank line when the HTML is rendered. For example, in this screenshot I have the source for my home page. There is some code in my header.html file that will allow me to put blog badges or logos in the future to be rendered in the header, but there currently isn’t anything in my config to make an image display. Yet, Hugo will render that line, see that there isn’t anything to do, and leave a blank line.

uMatrix Whitelist

I had looked around a little bit for minifying specifically regarding Hugo, but I realized that it wasn’t really something that was out there it seemed. I took a little bit off from it and learned a bit about npm and NodeJS in general from a couple other projects, and realized that it was probably the perfect way to integrate minifying into CI.

I went out searching for how others had used minifying npm packages (there are quite a few out there for minifying various resources) in their own setups. This led me to the most perfect blog post from Bad Sector Labs about using some minifying with a static site, using GitLab-CI nonetheless! This was perfect, as it really laid out everything that I was wanting to do, and how to do it.

I went out and made a new image in my GitLab repo’s registry from the latest official Node docker image, installed a few npm packages for minifying HTML, CSS, JS, JSON, and images (JPG, PNG, SVG) and, of course, Hugo. I then took it to my CI script and implemented the beautifully simple method from Bad Sector Labs for all of the packages. All of the image minifying is on separate lines so I can customize parameters from imagemin if I’m wanting to in the future.

As you’ll notice, these will find files that haven’t already been minified by excluding the .min prefix right before the file extension when using find. I had some issues with uglifyjs breaking the JS used to power the search on my site, and the fix was to not have it re-minify anything. I decided it’d probably be best to include it on everything just to be safe, and to create a standard of ending files in *.min.* if i’ve already minified something.

So there you have it, a quick way to minify all assets in a Hugo site pushed to GitLab Pages through GitLab-CI. Now, all pages are down to one single long line of HTML, referencing one long line of CSS and single long lines of JS when called upon.