
Up & Running With Hugo Part I: Building Your First Site
The popular static site generator written in GoLang - Hugo - has taken the community by storm. It brings all the benefits of a static site generator - 100% Flexibility, Security, Speed - but also steals the show otherwise π Hugo + Jekyll Benchmarked. In fact, the Forestry.io website is built with Hugo.
For this week on Frontend Friday, we’ll be covering how to get set up with Hugo on your local machine, including setting up a theme and customizing it, as well as writing your own CSS & JS.
How is this different from Hugo’s Quick Start guide? We’ll be using Hugo Boilerplate, a continuously maintained boilerplate project for Hugo sites that offers a modern developer workflow on top of Hugo.
Table of Contents
- Setting up Hugo on your local machine
- Adding Content & Installing a Theme
- Customizing Your Site
- Customizing Your Theme
- Next Steps
1) Setting Up Hugo
To get started, download the Hugo Boilerplate, and unzip the archive somewhere on your computer. You’ll also have to have Node.js and NPM installed, just follow the instructions on Node’s download page.
Hugo generates a project structure for you automatically. In the boilerplate project, this is the hugo/
directory. Inside of this directory are various folders containing your site’s content, layouts, and assets (e.g, CSS, JS, and images). Take a look at the breakdown of the boilerplates structure outlined below - I left out a few directories and files for clarity:
.
βββ hugo/ // The Hugo project; content, data and static files
| βββ .forestry/ // Contains Forestry.io configuration files
| βββ content/ // Where all site content is stored
| βββ data/ // TOML, YAML or JSON files containing site data
| βββ layouts/ // Your site's layouts
| | βββ partials/ // Your site's partials
| | βββ shortcodes/ // Your site's shortcodes
| βββ static/ // Where all static files live
| | βββ css/ // Where compiled CSS files live
| | βββ img/ // Where user images are stored
| | βββ js/ // Where compiled JS files live
| | βββ svg/ // Where svg are stored
| βββ config.toml // The Hugo configuration file
ββββ src/
βββ css // CSS/SCSS source files to be compiled to /css/
βββ js // JS source files to be compiled to /js/
To get the project up and running, open up a terminal window and navigate to the boilerplate folder (either hugo-boilerplate/
or hugo-boilerplate-master/
):
cd path/to/hugo-boilerplate/
Then install all of the project dependencies by running:
npm install
To start the development server and open it up in your browser, simply run:
npm start
2) Setting Up Your Site
To get started, we’re going to add new content to the site. To do so, we’ll need to update the content to the hugo/content/
folder.
Update A Post
To start, let’s update the example post shipped with the Hugo Boilerplate. Open up hugo/content/posts/example.md
in your text editor. You’ll see title
front matter field and some example markdown content.
---
title: "Welcome to Hugo!"
---
Youβll find this post in your `content/posts` directory.
To add new posts, simply add a file in the `content/posts` directory that follows the convention `name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea of how it works.
Hugo also offers powerful support for code snippets:
package main
import "fmt"
func print_hi(name string) {
fmt.Println("Hi, ", name)
}
func main() {
print_hi("Tom")
}
//=> prints 'Hi, Tom' to STDOUT.
Check out the [Hugo docs][hugo-docs] for more info on how to get the most out of Hugo. File all bugs/feature requests at [Hugoβs GitHub repo][hugo-gh]. If you have questions, you can ask them on [Hugo Community][hugo-community].
[hugo-docs]: https://gohugo.io/documentation/
[hugo-gh]: https://github.com/gohugoio/hugo
[hugo-community]: https://discourse.gohugo.io/
This post is missing a date! Try adding it by adding the following to the post’s Front Matter:
date: "YYYY-MM-DDTHH:MM:SS-00:00"
YYYY-MM-DDTHH:MM:SS-00:00
with a valid date, e.g, 2018-01-01T12:42:00-00:00
. If your date is in the future, Hugo wont build this post when doing production builds.
Save your changes and then view the updated post in your browser at http://localhost:3000/. The date in front of your “Welcome to Hugo!” post should have changed.
Create A New Post
Now let’s try creating a new post. We’ll use Hugo’s built-in commands to generate our new post. In the boilerplate, Hugo is added as an NPM dependency, so we can access it by running:
npm run hugo -- <command> --<param>
Create your first post by running:
npm run hugo -- new posts/my-first-post.md
This will create your new post at hugo/content/posts/my-first-post.md
as a markdown file. Open this file in your favorite text editor.
---
title: "My First Post"
date: "2018-01-31T14:24:17-04:00"
draft: true
---
In this file, we have Front Matter (structured metadata for the page) that can be used in your templates. Below the front matter, we can add markdown content as well.
Try adding the following to the file and then save your changes.
## Hello world
Hi, I am the *Hugo Boilerplate*. I hope you are enjoying this guide!
You can view the updated post in your browser at http://localhost:3000/posts/my-first-post/.
Adding A Theme
Right now your new site isn’t looking very pretty. Let’s fix that by adding a pre-built Hugo theme from the Hugo Theme Gallery, built by one of Hugo’s great community contributors.
We’re going to use the Casper theme by @vjeantet. We’ll do this by adding the theme to the hugo/themes/
directory, specifically hugo/themes/hugo-theme-casper/
. You’ll have to add these inside your hugo/
directory.
Download the theme, unzip the archive and then copy the entire contents to hugo/themes/hugo-theme-casper/
.
Next, you’ll need to update your site’s configuration with any of the theme-specific configurations.
Open hugo/config.toml
in your favorite text editor, and replace the contents with the following:
baseURL= "/"
languageCode= "en"
title= "Hugo Boilerplate"
paginate = 5
copyright = "All rights reserved - 2018"
theme = "hugo-theme-casper"
disableKinds = ["taxonomy", "taxonomyTerm"]
[params]
description = "Welcome to my website"
metadescription = "Used as 'description' meta tag for both home and index pages. If not set, 'description' will be used instead"
cover = ""
author = "YOUR_NAME"
authorlocation = "Earth, Milky Way Galaxy"
authorwebsite = ""
authorbio= ""
logo = ""
hjsStyle = "default"
paginatedsections = ["posts"]
For a full list of available configuration docs, see the theme documentation.
Finally, the boilerplate comes with some example layouts for developers that are building from scratch. Let’s remove these for now by running:
rm -r hugo/layouts/
Now head back over to the browser and check out your updated site!
3) Customizing Your Site
Now that we’ve set up a basic working site with a theme, you’ll probably want to personalize it.
First, we’ll customize the site params. Open up hugo/config.toml
once more, and update the following as you see fit:
title = "Hugo Boilerplate"
description = "Welcome to my website"
metadescription = "Used as 'description' meta tag for both home and index pages. If not set, 'description' will be used instead"
author = "YOUR_NAME"
Next, we’ll update the default hero image to something else. Open up hugo/config.toml
and find \[params\]
. Below, find the parameter cover
and update it to /img/darius-soodmand-116253.jpg
, and save your changes.
Now head back to your browser to see your updated site. It won’t look exactly like the screenshot above but don’t worry we’ll get there.
4) Customizing Your Theme
Now that you’ve customized your site to be a little more personalized, we’ll focus on the most powerful aspect of Hugo and this boilerplate: powerful yet simple templating.
Earlier we added the Casper theme to the site, which allows Hugo to use all of the HTML layouts stored at hugo/themes/hugo-theme-casper/layouts/
to generate your site.
Now, we’ll extend the theme by using Hugo’s template inheritance.
Any layouts stored in hugo/layouts/
will override any layout with the same name in theme’s layouts directory, allowing us to customize our site without messing with the theme.
Custom CSS & Javascript
Along with Hugo, this boilerplate comes with a development server that automatically post-processes CSS & JS for the browser. Any CSS, JS, or images found in the src/
folder will be processed and automatically moved to hugo/static/
.
Let’s add these to your theme so that you can customize it as needed. We’ll copy the base layout of the theme and add the boilerplate’s custom CSS and JS files to the layout.
First, we’ll copy the header partial of the theme to the hugo/layouts/partials/
directory:
mkdir -p hugo/layouts/partials/
cp hugo/themes/hugo-theme-casper/layouts/partials/header.html hugo/layouts/partials/header.html
Open hugo/layouts/partials/header.html
in your favorite text editor and find the following:
<link rel="stylesheet" type="text/css" href="{{ "css/screen.css" | relURL}}" />
<link rel="stylesheet" type="text/css" href="{{ "css/nav.css" | relURL}}" />
Below this add:
<link rel="stylesheet" type="text/css" href="{{ "css/styles.min.css" | relURL}}" />
Next, we’ll copy the partial footer.html
to the hugo/layouts/partials/
directory so we can add our custom JS:
cp hugo/themes/hugo-theme-casper/layouts/partials/footer.html hugo/layouts/partials/footer.html
Open hugo/layouts/partials/footer.html
and find the following:
<script type="text/javascript" src="{{"js/jquery.js" | relURL}}"></script>
<script type="text/javascript" src="{{"js/jquery.fitvids.js" | relURL}}"></script>
<script type="text/javascript" src="{{"js/index.js" | relURL}}"></script>
Below this add:
<script type="text/javascript" src="{{"js/scripts.min.js" | relURL}}"></script>
Now all of your custom CSS and JS will be used on the site.
Let’s give it a try by expanding the height of the main header. Open src/css/styles.css
and adding the following to the bottom of the file:
.tag-head.main-header {
height: 80vh;
}
Head back over to your browser to see the final result!
5) Next Steps
Now you’re all set to begin building your static site with Hugo!
Feel free to continue using the Casper theme, or start from scratch using the hugo/layouts/
directory.
Check out the following further reading to learn more about Hugo:
Up next
Next week we’ll be releasing a post on setting up version control with Git to facilitate continuous integration and continuous deployment to various hosting providers using Forestry, the CMS for static sites built with Hugo and Jekyll.
Join us every Friday π
Frontend Friday is a weekly series where we write in-depth posts about modern web development.
Next week: Up & Running with Hugo Part II: Continuous Integration & Continuous Deployments
Last week: We looked at integrating a performant search into your static site: Static search with Hugo + Algolia .
Have something to add?
Caught a mistake or want to contribute to the blog? Edit this page on Github!