Using Gulp with Hugo

All the HTML for this site is generated by a static site generator called Hugo1. There are hundreds, maybe thousands, of static site generators available. I like about Hugo because it’s featureful, simple, and fast. Its templates avoid turning the HTML I know and hate into something equally painful but unfamiliar. It generates pages very quickly and in parallel.

Hugo

Hugo doesn’t try to handle anything related to minifying Javascript, HTML, CSS, images, etc. It has a directory called static that it copies into your compiled site without modification. This means you’re free to handle these tasks using whatever tool you think is best, as long as you eventually place your assets into this static directory.

Gulp

I’m handling these tasks with Gulp2. See their docs for an in depth explanation of how to use it, I’m just going to take you through an example of using it in combination with Hugo.

Using them together

First let’s create a new hugo site site and new piece of content.

$ hugo new site hugo-gulp-example

$ cd hugo-gulp-example

$ hugo new about.md

Add some content to about.md:

+++
date = "2015-01-08T08:36:54-07:00"
draft = true
title = "about"
+++

All about hugo and gulp.

Then we’ll create a minimal theme for single pages, like our about page. Do this by creating a _default/single.html file within the Hugo layouts directory with the following contents:

<html>
<head>
  <link rel="stylesheet" type="text/css" href="/css/theme.css">
</head>
<body>
  Single page layout:

  {{ .Content }}
</body>
</html>

Now’s a good time to make sure everything is working so far by running hugo server --watch --buildDrafts=true and then visiting localhost:/about/.

This page shouldn’t be styled yet since we haven’t actually created our css file yet. We’re going to create it via Less3, which we’ll compile with gulp.

Create a less directory and a theme.less file within it with the following contents:

@bgcolor: #ff0000;

body {
  background-color: @bgcolor;
}

Compiling Less

First make sure you have gulp, less, and the gulp-less plugin installed:

$ npm install --global gulp

$ npm install --save-dev gulp

$ npm install --global less

$ npm install gulp-less

Finally, create a file called gulpfile.js. Our directory structure now looks like this:

.
├── archetypes
├── config.toml
├── content
│   └── about.md
├── gulpfile.js
├── layouts
│   └── _default
│       └── single.html
├── less
│   └── theme.less
├── public
│   ├── about
│   │   └── index.html
│   ├── index.html
│   ├── index.xml
│   └── sitemap.xml
├── static

Now we’ll write our gulpfile to compile our less and output the css to Hugo’s static directory, so that it’ll placed in the correct place when we run hugo build.

Edit gulpfile.js to look like so:

var gulp = require('gulp')
var less = require('gulp-less')

gulp.task('css', function() {
  gulp.src('less/*.less')
    .pipe(less())
    .pipe(gulp.dest('static/css/'))
})

gulp.task('default', ['css'])

With the gulpfile in order, we can now run gulp to run the default gulp task, which in our case just runs the ‘css’ task which converts Less files to CSS files and places them in the static/css directory. The contents of the static directory are copied into Hugo’s public directory, so they will be accessible to our theme.

Now that we’ve run gulp, if we start our Hugo server again (or refresh if it’s still running ) and visit the about page (localhost:<port>/about/), it should now have a red background.

This basic setup can be easily extended handle minification and concatenation as well.

In my workflow, I generally set up a gulp watch task, and then leave both the hugo server and the gulp watch task running as I develop, that way any modifications to my Less files are compiled immediately, and are picked up whenever I save a content or layout file in Hugo.