Hugo 102: Setting Up

Hugo is a static site generator that converts markdown files (.md) to html pages. Let’s discover how we can build a blog using it, and discuss some configuration options that will make the experience better.

Step 1 - “Install” Hugo

  1. Download the latest extended version for your OS from Hugo Releases
  2. Extract Hugo in a folder of your choice
  3. (Optional) Add Hugo folder to path - if not, then replace the hugo command with the full path to Hugo, ie "c:\program files\hugo\hugo"

Step 2 - Create a new blog

  1. Launch a new command prompt and navigate to the folder which will contain the new site.
  2. Create a new hugo using hugo new site my-blog. A folder named “my-blog” will be created.
  3. Download a new theme, preferably beatiful hugo.
  4. Extract and copy the new theme inside my-blog/themes/
  5. Rename theme folder from beautifulhugo-master to beautifulhugo
  6. Open the config file (my-blog/config.toml) and edit the theme line theme = "beatifulhugo" to select the new theme
  7. Create a new post hugo new post/first-post.md
  8. Run the deveopment server (hugo serve -D -w)
  9. Preview the new site on http://localhost:1313 - unless port 1313 is already used, in which case the new port will be listed in the development server’s output

Step 3 - Content Management

Although there are a lot of ways to organize content in hugo, I prefer to place each post in a separate folder named yyyy-mm-dd title, also I like to group these folders by year. Finally since each post lies in each own folder it should be named as index.md.

So the full path for each post my-blog/content/post/yyyy/yyyy-mm-dd title/index.md

This is how my folder structure looks like

my-blog
│
├── cv
│   └── index.md
│
├── content
│   ├── post
│   │   ├── 2018
│   │   │   ├── 2018-03-15 Hugo Gallery Shortcode
│   │   │   │   ├── index.md
│   │   │   │   └── feature.png  
│   │   │   │   
│   │   │   └── 2018-09-11 Hugo 101 Static Site Generators
│   │   │       ├── index.md
│   │   │       └── feature.png  

That approach both keeps all post files together in a folder and isolates them from the rest posts allowing for easier editing as each time we have to handle only one folder containing exactly what we need.

By default hugo will use the post title to create the url of each posts but this approach might create issues if we decide to change the title of the post or if we don’t necessarily like to match the url with the post’s title. Also since post images will be under the same url, changing post title will require changing all image urls. A better approach is to use “slugs” a slug is a custom url part that we assign to each post.

First we need to instruct hugo to use the slugs so we edit my-blog\confg.toml and add the following lines

[permalinks]
  post = "/:year/:slug/"

This instructs hugo to create a url that consists of the year and the slug for each post.

Now in order to set the slug for each post we need to understand what these index.md files contain. Each post file (index.md in our case) contains the text of the post and some meta-data, called frontmatter. The frontmatter must appear in the beggining of each file between --- and consists of name: value pairs. For example the frontmatter of this page is

---
title: "Hugo 102: Setting Up"
date: 2019-03-15
tags: ["hugo"]
slug: "hugo-setup"
image: "2019/hugo-setup/featured.png"
---

the year of the date and the slug are used to construct the url of each post. Note that the image field here will be used in the home page of the post and, thus, it’s value must be relative to the root of blog.

Step 4 - Content

The actual content of each post starts after the front matter. Everything we write bellow the frontmatter will appear in the post’s body. The content should be formatted in markdown but also regular html will work.

As a very short intro to markdown:

  • prefixing any line with #, ##, ###, ####, #####, ###### will create headers
  • enclosing any text in * or ** will render it using italic or bold
  • prexiing any lines with - will create lists

Step 5 - Generating

By defaut hugo marks all new posts as drafts, before generating check that no post has a draft: true field in it’s frontmatter

To generate the site use the hugo command. It will create a folder named public with all the content of the site. You can publish your site by uploading the contents of the public to any host.

hugo