Hugo + Brunch, Advanced template organization


I am a new with a Hugo, but I have experience with the frontend development.
I met with Hugo a two months ago and I love the concept of the static websites, the speed of website generating, loading in browser and other features. I believe the Hugo have the great chances to be a winner in the implementations of the JAMstack architecture, but we all need to help for it happen.

I would like to share my ideas, thoughts, experience about how to deal with the Brunch as assets building tools and how I have organized the Hugo template for the fast starting of a new project (IMHO).

Why Brunch?

This is yet another option for the Hugo developers to create websites.The Brunch is a fast building tool, like Gulp or Webpack, but simple to configure and expand. I think it can be useful for many developers for complete of their assets tasks.
Also you can see the compare information about Brunch competitors here.

Brunch plugin

For combining the best parts of both worlds (Hugo and Brunch) I have wrote the simple Brunch plugin - hugo-brunch. It adds the ability to compile the Hugo code from Brunch. You can find more information here.

How to use the hugo-brunch?

For this reason I created the hugo-init project - a starter kit for creating a homepage static website. You can use it as a starting point for development different kinds of the Hugo page templates.

Features of the hugo-init

  • It uses the one building tool to automate all tasks.
  • Includes the recommendations for the DRY and maintainable code by using the partials for the different parts of a webpage.
  • Ability for configure of the Hugo execution by passing the flags. You can configure the hugo-brunch plugin in the brunch-config.js file.
  • Building a website for the one of three types of environment: development, staging (preview), production (build).
  • You can install a certain javascript package via npm and use it as a module by require (for CommonJS) or import (for ES6) it in your js code. Also you can put the js code of some library (as I done with Modernizr) into the libs/ folder and use this library by calling the require or import instruction in your app.
  • From start you have the Modernizr in the src/scripts/libs/ folder, PostCSS-cssnext and Babel support by using the corresponding brunch plugins. You can redefine that and use the libraries that you needed. You need to put a library into the libs/ folder or install a certain package via NPM or install the Brunch plugin to support different type of technologies, libraries, frameworks. Here the list of Brunch plugins.
  • Task for minification of the html files. When you build your website in the staging or production mode your html will be optimized by removing the whitespaces. This task are use the html-minifier package to complete this.

Also you can find the Sass and jQuery support in the sass branch of the hugo-init repository. This is another version of project without the Babel and PostCSS-cssnext.

Please note: this starter kit is under development. Therefore the things can change.

What about the advanced template organization?

I used this version of site/layouts/_default/baseof.html file as a primary template for creating different type of pages:

<!doctype html>
<html class="no-js" lang="{{ .Site.LanguageCode | default "en" }}">
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ block "title" . }}{{ .Site.Title }}{{ with .Title }} - {{ . }}{{ end }}{{ end }}</title>
    <meta name="description" content="{{ .Description }}">
    {{- if eq (getenv "HUGO_ENV") "production" | or (eq .Site.Params.env "production") -}}
      <meta name="robots" content="index, follow">
    {{- else -}}
      <meta name="robots" content="noindex, nofollow">
    {{- end -}}
    <link rel="shortcut icon" href="favicon.ico">
    {{- block "head-includes" . -}}
      {{- partial "head-includes.html" . -}}
    {{- end -}}
    {{- "<!--[if lte IE 9]>" | safeHTML -}}
        <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="">upgrade your browser</a> to improve your experience and security.</p>
    {{- "<![endif]-->" | safeHTML -}}
    {{- block "no-scripts" . -}}
      <noscript>For full functionality of this site it is necessary to enable JavaScript. Here are the <a href="//" target="_blank" rel="noreferrer nofollow">instructions how to enable JavaScript in your web browser</a>.</noscript>    
    {{- end -}}
    {{- block "header" . -}}{{- end -}}
    {{- block "main" . -}}{{- end -}}
    {{- block "footer" . -}}{{- end -}}
    {{- block "scripts" . -}}
      {{- partial "scripts.html" . -}}
    {{- end -}}
    {{- if eq (getenv "HUGO_ENV") "production" | or (eq .Site.Params.env "production") | and .Site.GoogleAnalytics -}}
      {{- template "_internal/google_analytics_async.html" . -}}
    {{- end -}}

The idea is creating the general template by using the block constructs. After I used the partials for injecting the different parts of webpage. Or I can create the html page and define the different blocks on it without using of partials. In this flexible way I can create almost any type of webpage by inherit the functionality from the base template. Here is example of the site/layouts/index.html page:

{{ define "header" }}
  {{- partial "header.html" . -}}
{{ end }}
{{ define "main" }}
    {{ .Content }}
{{ end }}
{{ define "footer" }}
  {{- partial "footer.html" . -}}
{{ end }}

This approach is simplify the development and maintenance of website.
More details you can find in the hugo-init code, not all the features are covered in this post.

This is a not required to follow this template, because any website are different and unique. Feel free to customize this template to fit your needs.

Please let me know about your thoughts according to the things covered in this post.

I hope this information will be useful for people.
Have a great time

1 Like

I have the same template organization as yours and it works great so far.

I still need to review Brunch plugin, but thanks for sharing.

Thanks @magis

Great to hear that somebody is thinking in the similar way!

Today I have added a task for minification of the html files into the hugo-init project. Your html will be optimized by removing the unused whitespaces when you build your website in the staging or production mode.This gives you the optimized webpages for fast loading in a browser.

1 Like

Today I have finished the migration of the codebase for the hugo-init project to support the Babel and PostCSS-cssnext.

Also you can find the Sass and jQuery support in the sass branch of the hugo-init repository. This is another version of project, but without the Babel and PostCSS.

1 Like

Hi Sergey, just tried your project - awesome. But in my case Brunch is not picking up on changes in the site folder. If I change CSS everything works. If I change for example layouts/index.html or content/ Hugo is rebuilding but Brunch is not picking up on that and so not reloading the browser. Manual reload shows the changes in above files. How come?

1 Like

Hello Leo,

Thank you for your kind of words and thanks for your interest to the hugo-init project.
For a couple days ago I have faced with issue when the updated files doesn’t reloads in some browsers properly. For some reasons this issue is appears in the Firefox and IE browsers. Perhaps this behavior is related with the auto-reload-brunch plugin.

I have some quick fix for these browsers. You need to add this config for the auto-reload-brunch plugin into your brunch-config.js file:

plugins: {
  autoReload: {
    delay: 200

This is a workaround for the current moment.

Here is a visual description about current behavior and how to fix the issue:
Issue with file reloading

Also I opened the issue in the hugo-init repository.

Thank you for remind me to share with community. Please let me know if this helps.
Sorry for the inconvenience this may cause