Hugo Tutorial: Themeless & Gitless Introduction to Hugo

 

In this tutorial we use the static site generator Hugo to create a simple website that…

 

Page contents

 

News

2020-April & March  Significant updates in this tutorial, including renaming and renumbering some sections, rewriting 14.2. markup, and creating 17.5.2. taxonomies🏷, 17.5.3. Case sensitivity of variables, and 19.2. Learn about Hugo bundles.

Prerequisites

Background

This tutorial assumes that you have experience…​

  • creating simple HTML+CSS websites

  • and launching apps from a command line.

It does not assume anything about what platform and apps (other than Hugo) that you are using.

Mindset

Also this tutorial assumes that you…

  • would like to learn about some of the inner workings of Hugo

  • and are comfortable tinkering with code.

In other words, this tutorial is for you if you are a “hacker” in the following sense.

hacker

“A person who delights in having an intimate understanding of the internal workings of a system, computers and computer networks in particular. The term is often misused in a pejorative context, where "cracker" would be the correct term. See also: cracker”

Tools

Extended Hugo

To follow the steps in this tutorial, you need to have an extended version of Hugo installed on your system. Information about this is in Step 0 and Step 1 below.

Editor, terminal, and browsers

To develop a website with Hugo, you need to be able to access the following interfaces or views of your system.

InterfaceUsed For

command line
(terminal)[3]

running hugo commands, including starting and stopping the Hugo server

web browser

viewing http://localhost:1313/

file browser

viewing and managing Hugo-related files and directories

plain text editor

editing the website’s archetypes, assets, configuration, content, and layout files

Most platforms have built-in apps for accessing the above four interfaces. If you would like to use an app that integrates some of these interfaces, I recommend one of the following.

All three of these run on multiple platforms and are free/libre open source software (FLOSS).

For more about integrated development environments, see these pages at wikipedia.org:

 

Shell tip🐚

When you use a command-line interface or terminal, you do it in a shell, which is a layer between you and the operating system. I’ve tried to write this article so that the commands work in most shells. The main shell advice I have is the following.

💡︎

Use a shell that saves the command-line history (or buffer) between sessions. This way you can use the Up Arrow and Down Arrow keys to step through your command history.

  • On nix-based platforms, most command-line shells (bash, fish, zsh, etc.) do this by default.

  • On Windows, PowerShell saves the command-line buffer by default, but cmd.exe[4] does not. This is one reason I prefer PowerShell to cmd.exe.

For more information about shells, see Shell (computing) - Wikipedia.

Hugo preferences

Website source files below $HOME (~)

In the steps below we create a website out of files in a directory named Hugo. I recommend that you put this Hugo directory somewhere below your home directory because…

  1. most backup apps automatically back up your home directory,

  2. most sync apps, such as Dropbox and Sync.com, sync a subdirectory of the home directory,[5]

  3. you and hugo should not have permission problems creating, editing, moving, or deleting files and directories in your home directory,

  4. and in most shells, you can use cd ~ to go to your home directory.[6]

To find out your home directory, open a terminal and at the prompt run one of the following commands.

  • In nix-based shells and PowerShell, run either:

    • echo $HOME

    • cd ~ (this will change directory to ~ (your home directory))

  • In cmd.exe, run:

    • set home

Executable anywhere on $PATH

The hugo executable is one file — with no dependencies🎉 — and it can be put anywhere on your path. To find out your path, run one of the following commands at a command-line prompt.

  • In a nix-based shell, run:

    • echo $PATH

  • In PowerShell, run:

    • $Env:Path

  • In cmd.exe, run:

    • set path

💡︎
If you use a package manager to install hugo you will not need to deal with your path because the package manager will take care of that.

Information about installing Hugo is in Step 0 below.

Non-standard Hugo preferences

There are some things that I do in the steps below that you may wonder about if you have already used Hugo. The following list of my preferences will, I hope, help you to understand why things are the way they are in this tutorial.

  • I want to deal with a minimal number of layout[7] files and I do not want to have to think about Hugo’s layout lookup order.

  • The layout file for a Hugo website’s home page can be named home.html or index.html. I prefer to name it home.html because the word index is semantically overloaded in Hugo.

  • For Hugo configuration, I prefer YAML to TOML[8] and thus use a config.yaml file rather than a config.toml file. Many Hugo themes and tutorials use a config.toml.

  • In YAML syntax, I like to minimize the use of commas, quotation marks, and square brackets.

Article style

This article uses the following admonition icons.

IconMeaning

‼︎

Important

👉️

Note

💡︎

Tip

0. Install extended hugo

To install an extended version of hugo, do one of the following.

 

💡︎

1. Check your hugo

To check that hugo is on your path, is version 0.43 or higher, and is an extended version, run the following at a command prompt:

hugo version

You should see something like this:

Hugo Static Site Generator v0.71.1/extended windows/amd64 BuildDate: unknown
                                      👆
‼︎
Make sure you are using Hugo Extended v0.43 or later because old and unextended versions of Hugo do not support SCSS (Sassy CSS), which we use in the site we build below.

 

💡︎
  • You can get more information about your version of Hugo with the hugo env command.

  • You can find out what directory the hugo executable is in with one of the following shell commands.

    • In a nix-based shell, run:

      • which hugo

    • In PowerShell, run:

    • In cmd.exe, run:

      • where hugo

2. View Hugo’s built-in help

To learn about Hugo’s commands and flags run this command at a command prompt:

hugo -h | more

The trailing | more (“pipe more”) in the above command pipes[12] the output of hugo -h through the more pager. Within more, you can press Space to page down and press q to quit.

👉️
  • -h, --help, and help are equivalent hugo command-line arguments. The results are on Infinite Ink’s Hugo CLI page.

  • | more, which is equivalent to |more (with no whitespace), works in the command-line interface of most platforms, including Windows[13] and nix-based platforms (BSD, Linux, macOS, Unix, etc.).

3. Create Hugo and Backups directories

Create a directory named Hugo, which will contain all the Hugo-related files and directories we use in this article. Within this Hugo directory, create a subdirectory named Backups. You should now have this directory structure:

Hugo/
  Backups/

There is nothing special about these two directory names, but to be able to easily follow the steps below, I recommend that you use these names.

💡︎
I recommend that you put this Hugo directory somewhere below your home directory. Details about this tip are in Hugo preferences above.

4. Download the TGIH site skeleton

Download the site skeleton from the themeless-gitless-intro-hugo repository in Infinite Ink’s GitHub account. One way to download it is to click on the following link of the repo’s .zip file.

After themeless-gitless-intro-hugo-master.zip has downloaded, unzip it and put the TGIH[14] directory in your Hugo directory. Your Hugo directory will now look like this:

Hugo/
  Backups/
  TGIH/

Before we edit the TGIH files, make a backup copy of the freshly downloaded and unzipped TGIH directory and include some historical information in the name of this backup directory, for example you could append the download date like this:

Hugo/
  Backups/
    TGIH-2020-05-29/
  TGIH/

 

4.1. Explore the TGIH directory

The TGIH directory currently looks like this:

  TGIH/
    archetypes/
      default.md
    assets/
      style.scss
    content/
      articles/
        markdown-experiments.md
    layouts/
      _default/
        baseof.html
        home.html
        list.html
        single.html
        tag.html
    static/
      images/
        go-logo_black.png
    config.yaml

 

4.1.1. No themes directory

If you are familiar with Hugo, you may wonder why there is no themes/ directory. A themes/ directory is not required and the site we build below does not use one — that’s why this tutorial’s subtitle is Themeless & Gitless Introduction to Hugo.

 

4.1.2. Terminology: “project root directory”

For the rest of this article we work in this TGIH/ directory, which is called the…

  • project base directory,

  • project root directory,

  • project working directory,

  • project directory,

  • project root,

  • or workingdir.

The Backups/TGIH-2020-05-29/ directory will come into play only if there is a problem with the website.

 

4.2. Provenance

Most of the files in this directory were forked from Niklas Fasching's Hugo whitespace theme. The article markdown-experiments.md was forked from markdown-it. The image go-logo_black.png is the Go logo.

Thank you Niklas, markdown-it, and golang.org!

5. Build and view the site

These files are enough to build the beginning of a website.

5.1. Build the site

At a command-line prompt, go to the TGIH directory and run:

hugo server -D
            👆

The -D flag, which is equivalent to the --buildDrafts flag, tells the hugo server command to build drafts.

The Hugo server displays a lot of information, including this at the top:

Building sites …
                   | EN
+------------------+----+
  Pages            | 15
  Paginator pages  |  0
  Non-page files   |  0
  Static files     |  1
  Processed images |  0
  Aliases          |  0
  Sitemaps         |  1
  Cleaned          |  0

And this at the bottom:

Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

5.2. View the site

In a web browser, go to…

http://localhost:1313/
   👆
   notice that this is not https

You should see something like the following.

My New Hugo Site screenshot

Click on the about link in the navigation bar and you will get a “404 page not found” page. We fix this in Step 12 below.

Click on the yellow highlighted Markdown Experiments link and you will see a page that contains HTML elements, such as headers, lists, and bolded text. The hugo command generated this HTML page from the file content/articles/markdown-experiments.md. Details about this .md file are in Step 6 below.

5.3. Explore the TGIH directory again

In a file browser, note that the hugo server command generated a resources/_gen/ directory so now the TGIH directory looks like this:

  TGIH/
    archetypes/
      default.md
    assets/
      style.scss
    content/
      articles/
        markdown-experiments.md
    layouts/
      _default/
        baseof.html
        home.html
        list.html
        single.html
        tag.html
    resources/
      _gen/
        assets/
          scss/
            style.scss_f300667da4f5b5f84e1a9e0702b2fdde.content
            style.scss_f300667da4f5b5f84e1a9e0702b2fdde.json
          images/
    static/
      images/
        go-logo_black.png
    config.yaml

5.4. Hugo server tips

  • If you leave this hugo server running, Hugo will LiveReload the site when you make changes.

  • While the server is running, you can open another terminal and run other hugo commands there. If you regularly use multiple terminals, I recommend using a tabbed terminal emulator.

  • If there is a problem with the site, use Ctrl-C to stop the Hugo server and then restart it.

For more Hugo server tips, see Infinite Ink’s Debugging Your Hugo Website.

6. Anatomy of a content file

This section is about looking at a file in the content/ directory. You do not need to make any edits, but it’s OK if you do.

Use your text editor to open markdown-experiments.md, which is in the content/articles/ directory. Abstractly a Hugo content file is structured like this:

header         

body
 

In Hugo the header is called front matter and the body is called various things, including:

  • body

  • body content

  • Content

  • content body

  • main matter

  • RawContent

In this Hugo Tutorial: Themeless & Gitless Introduction to Hugo, the body is called Content (with the “C” capitalized). Here is the anatomy of a Hugo content file using this terminology:

front matter

Content
 

Details are below.

6.1. Front matter

The file begins with with three dashes[15] --- These dashes tell the hugo command that what follows is YAML front matter. Front matter is used to set page variables. For more information, see these pages on the gohugo.io site:

Front matter is also known as metadata. A Hugo variable is also known as a parameter (or more precisely as a parameter key and a parameter value).

‼︎

Front matter is required in a Hugo content file. If you do not need to specify any metadata, use empty front matter, for example this:

---
---

or this:

---
# This front matter is intentionally left blank.
---

6.2. Blank line

After the YAML front matter, which ends with ---, is a blank line.

👉️
If the front matter is in TOML or YAML format, this blank line is not required but if the front matter is in JSON format, it is required.

6.3. Content

After the blank line is the Content. Since the filename extension is .md, the hugo command interprets this part of the file as Markdown, a lightweight markup language.

👉️
  • I use “Content” — with an initial capital letter — to mean the part of the file after the front matter.

  • In Go Templates, which are discussed in Steps 11 and 15 below, this Content is sometimes available as {{ .Content }} and {{ .RawContent }}.

7. Content, configuration, and front-matter languages

7.1. Content markup languages

Hugo supports a lot of markup languages, including more than one flavor of Markdown. In this tutorial all the content files are interpreted as Goldmark-flavored Markdown (assuming you are using Hugo v0.60.0[16] or later).

7.2. Configuration and front-matter languages

In Hugo, you can use JSON, TOML, or YAML in…

  1. front matter of content files,

  2. site configuration files,

  3. and data files.

In this tutorial, we use YAML for the first two and do not use the third (data files).

To learn about YAML, see Infinite Ink’s YAML includes Atoms, Maps, and Lists.

8. Create one.md

Open a new terminal, make sure you are in the TGIH directory, and run:

hugo new articles/one.md
         ---------------
                👆
         this path is relative to TGIH/content/

The one.md file is created in the content/articles/ directory.

👉️
  • Do not specify content in the path because that is included automatically by the hugo new command

  • In Hugo forward slash (/) will work as a directory delimiter on any platform, including Windows.

  • Do not put a space or any whitespace character in the path or file name.

  • Separate words with a dash (-)[15] because the new-content archetype (discussed in Step 11 below) creates the article title by replacing dashes with spaces.

  • Use all lower case characters in the names of directories and files in the content/ directory because most web servers force URL paths to be all lower case.[17]

  • In Hugo, the default is to use the content file name (without the extension) as part of the web page URL.

Your TGIH/content/ directory now looks like this:

content/
  articles/
    markdown-experiments.md
    one.md

Look at http://localhost:1313/ in a web browser and the One and Markdown Experiments articles should be listed on the home page like this:

My New Hugo Site screenshot
💡︎

If you do not see both the One and Markdown Experiments articles listed, make sure:

  • hugo server is running with the -D flag

  • one.md is located in the articles/ directory

9. Edit one.md

Use a text editor to open one.md, which looks like this (with the date replaced with the date you created it):

---
# Important: If this is not a draft, comment out the next line
draft: true
title: One
date: 2019-05-16
# below are non-built-in parameters (lower case keys recommended)
subtitle:
tags:
  - hugo
  - intro
---

Below the blank line after the front matter add some markdown content, for example:

**Hello World!** This is written in *Markdown*, a lightweight markup language.

When you save your changes, the Hugo server will automatically update the markdownified web page. In Hugo markdownify means convert markdown to HTML.

9.1. Learn Markdown

To learn Markdown, see:

💡︎

A nice FLOSS multi-platform WYSIWYG Markdown editor is Mark Text.

10. Edit config.yaml🔧

The config.yaml file in the root of the TGIH directory is used to specify global variables. Use a text editor to open this file, which looks like this:

baseURL: https://example.org/
languageCode: en-us
title: My New Hugo Site

10.1. title

Use your text editor to add a comment, a blank line, and change the title to Hello World. The file will now look something like this:

# 2020-05-29: changed title

baseURL: https://example.org/
languageCode: en-us
title: Hello World

If the hugo server is running and the web browser is displaying http://localhost:1313/, the title will immediately change to Hello World when you save config.yaml.

‼︎
In a Hugo config file, variables, such as baseURL, languageCode, and title, are sometimes case sensitive so I recommend that you specify them using the upper- and lower-case letters that are specified at gohugo.io/getting-started/configuration/.

 

10.2. About configuring Hugo

In Hugo, there are many ways to specify global variables, including

  • in a file named config.json, config.toml, or config.yaml in the root of the project

  • in command-line flags

  • in environment variables

  • in multiple files in a config/ directory in the root of the project

To me, the simplest is to use config.yaml in a project’s root so that is what I use in this tutorial.

To view your site’s current configuration, which includes a lot of default settings, run the following command from the TGIH directory:

hugo config | more

For more information about configuring Hugo, see Configure Hugo at gohugo.io.

 

11. Edit the archetype for new .md content files

When you use the hugo new command to create a .md file (as we did in Step 8 above), Hugo uses archetypes/default.md as a template for the new file.

 

11.1. Open and view archetypes/default.md

Use a text editor to open default.md, which looks like this:

---
## Important: If this is a draft, next line should NOT begin with #
# draft: true
title: {{ replace .Name "-" " " | title }}
date: {{ dateFormat "2006-01-02" .Date }}
## below are user-defined parameters (lower case keys recommended)
subtitle:
tags:
  - tag1
  - tag2
---

I recommend that you do not edit this archetype file until Step 11.2 below.

 

11.1.1. Front matter

The double curly braces in in the title and date key values are Go Template code.

👉️
A curly brace is sometimes called a mustache or handlebar, but Go Templates are different from Mustache and Handlebar templates.

 

11.1.2. Content

Currently the Content part of this archetype file is empty. You can write some notes to yourself, some content snippets, or whatever you would like to be included in every .md file created with the hugo new command. For example, you could put something like the following bolded lines in the content part of your markdown archetype file.

---
## Important: If this is a draft, next line should NOT begin with #
# draft: true
title: {{ replace .Name "-" " " | title }}
date: {{ dateFormat "2006-01-02" .Date }}
## below are user-defined parameters (lower case keys recommended)
subtitle:
tags:
  - tag1
  - tag2
---

markdown here


<!--
  HTML, including an HTML comment like this, is OK in markdown
-->

HTML comments will not appear on a web page, but may be viewable if someone uses a web browser to “view page source” so be careful what you put in HTML comments.[18]

 

11.1.3. Go Template code works anywhere in an archetype file

You can include Go Template code anywhere in an archetype file, including in the Content section. I like to have an HTML comment that records the exact moment that I created the file by putting this in the Content section of my archetype file:

<!--
  created {{ now }}
-->

The above HTML comment is a note to self that my readers will not see unless they use their web browser to “view page source.”⁠[18]

 

11.2. Edit archetypes/default.md

In Step 12 we create more markdown content. In order to see how an archetype works, add the bolded text below to the Content part of default.md:

---
## Important: If this is a draft, next line should NOT begin with #
# draft: true
title: {{ replace .Name "-" " " | title }}
date: {{ dateFormat "2006-01-02" .Date }}
## below are user-defined parameters (lower case keys recommended)
subtitle:
tags:
  - tag1
  - tag2
---

markdown here


<!--
  created {{ now }}
-->

 

11.3. Save and close archetypes/default.md

Close the default.md archetype file so you do not accidentally edit it in the steps below.

 

11.4. Archetype references and tips

For more about Hugo archetypes, see:

 

💡︎

In Go Templates, including Hugo archetypes, layouts, and shortcodes,…

  • You can keep things DRY by using partials, which are basically Go-Template “includes.” This is useful if you have something that you want to include in multiple layout, shortcode, and/or archetype files and you Don’t want to Repeat Yourself. Note that partials reside in your project’s layouts/partials/ directory.

 

12. Create more content: another-one.md and about.md

Thanks to the updates to the archetype file we made in the last step, the .md files we create in this step will include some default text below the front matter.

At a command-line prompt, make sure you are in the TGIH directory, and run these two commands:

hugo new articles/another-one.md
hugo new about.md

The content directory now looks like this:

content/
  about.md
  articles/
    another-one.md
    markdown-experiments.md
    one.md

In your web browser, note that the about link in the navigation bar of all the http://localhost:1313/ pages now works.👍

13. Experiment with the content .md files

In a text editor open about.md, another-one.md, markdown-experiments.md, and one.md. Note that about.md and another-one.md include the Content that we added to the archetype file in Step 11.2.

 

13.1. Front matter

In the front matter, experiment with the following parameters.

 

13.1.1. draft

The beginning of the front matter in most of the .md files looks like this:

---
## Important: If this is a draft, next line should NOT begin with #
# draft: true

Turn at least one of these content files into a draft by changing the front matter to the following (i.e., remove the #  that is before draft: true).

---
## Important: If this is a draft, next line should NOT begin with #
draft: true
👉️
If a content file is a draft, the hugo command will process it only if the --buildDrafts flag, which is equivalent to the -D flag, is used.

 

13.1.2. date

The order of the articles listed on the home page (http://localhost:1313/) is based on the date parameter. Change the dates so that the order is changed.

‼︎
Make all dates today or earlier. By default hugo does not build any page with a date in the future.

To learn about other ways to order the article list, see Order Content at gohugo.io.

 

13.1.3. subtitle

The front matter includes a subtitle parameter key that has no value:

subtitle:

In some or all of the .md files add a value to this key, for example:

subtitle: this is a subtitle

Make sure to leave a space between the colon (:) and the subtitle value.

 

13.2. Content

After the YAML front matter, which ends with three dashes (---), I like to put a blank line before the Markdown Content.

👉️
If the front matter is in TOML or YAML format, this blank line is not required but if the front matter is in JSON format, it is required.

 

13.2.1. Include an image

The TGIH directory that you downloaded in Step 4 includes an image in the static/ subdirectory. To use this image in a TGIH .md file, use this Markdown syntax:

![Go Logo](/images/go-logo_black.png)
           👆
           notice this leading slash

When you save the .md file with this Markdown, the following image will be rendered on the web page.

Go Logo

This is the Go logo, which you can read about at blog.golang.org/go-brand.

💡︎

To specify the size and other aspects of an image, you can use Hugo’s built-in figure shortcode.

 

👉️

 

13.2.2. Include emoji codes

Include the following three emoji codes in the Content of at least one of the .md files.

:man_astronaut:
:star:
:woman_astronaut:
‼︎
These will not be rendered as emoji[21] until step “14.1 enableEmoji✨” below.

 

 

💡︎

This tip icon is the :bulb: emoji.

The titles of sections 14 and 14.1 below include the :wrench:, and :sparkles: emoji respectively.

 

14. Edit config.yaml again🔧

Open config.yaml in a text editor.

14.1. enableEmoji

Add something like the following four lines to your config.yaml. I like to surround a setting like this with blank lines to make it stand out from other configuration settings, especially any table or list, that might be above or below it.

 
# 2020-05-29: added next line
enableEmoji: true
 

As soon as you save config.yaml, the three emoji codes you specified above in Step 13.2.2 should render in the web browser as:

    👨‍🚀 ⭐ 👩‍🚀

 

14.2. markup

If you are using Hugo v0.60.0+ and want to use raw HTML in your Markdown, include the following nested map in your config.yaml.[22][23]

markup:
  goldmark:
    renderer:
      unsafe: true

With this “unsafe” setting, Hugo will pass raw HTML — for example <br> — through to the destination file.

‼︎
Without this “unsafe” setting, <br> and any other raw HTML in a Markdown source file will be replaced with <!-- raw HTML omitted --> in the markdownified[24] destination file.

Note that this setting is needed only if you are using Hugo’s default Markdown parser (Goldmark). For more about this, see…

15. Explore the layouts directory

The layouts directory looks like this:

layouts/
  _default/
    baseof.html
    home.html
    list.html
    single.html
    tag.html

These files — along with the .scss file in the assets/ directory — create the look and feel of the website.

15.1. About Hugo layout files

Each Hugo layout file…

  • is written in the Go Template language, which is also known as Go HTML,

  • can access site variables and page variables,

  • and has a file extension that signifies the output format (html in these TGIH layout files).

The TGIH website has three kinds of pages and Hugo renders them as follows:

KindUses base layout
baseof.html and
main block
from…
View example
rendering at

home

home.html

localhost:1313/

page

single.html

localhost:1313/about/

taxonomy

tag.html

localhost:1313/tags/tag1/

15.2. Edit home.html

Open home.html in a text editor. The following line is why drafts are highlighted in yellow on the home page.

<span {{ if .Draft }}style="background-color: yellow;"{{ end }}>{{ .Title }}</span>

 

Change yellow to red, blue, green, rebeccapurple, gray, lightgray, or any of the hundreds of web colors.

Next add some HTML under the h1 heading, for example:

<h1 class="title">{{ .Title }}</h1>

<!-- 2020-05-29: added next paragraph -->
<p>
Here are the articles on this website <strong>ordered by publication date</strong>, starting with the most recently published article.
</p>

 

This added paragraph is written in HTML, which is why it is within the HTML <p> and </p> tags. (Note that when you write in a lightweight markup language, such as Markdown, you do not need to use paragraph tags because paragraphs are delimited by blank lines.)

When you save these changes, the home page of the site (http://localhost:1313/) will change the draft highlight color and display the text that you put between <p> and </p>.

👉️
Another way to add text to the home web page is discussed in Infinite Ink’s Introduction to Hugo Bundles⁠🎁 in the section Branch bundle example.

 

15.3. Layout references and tips

For more about…

 

👉️

In Go HTML…

  • You can comment out executable code with the following comment syntax.

    {{/*
         Go HTML
         multi-line
         comment
    */}}
  • You can keep things DRY by using partials, which are basically Go-Template “includes.” This is useful if you have something that you want to include in multiple layout, shortcode, and/or archetype files and you Don’t want to Repeat Yourself. Note that partials reside in your project’s layouts/partials/ directory.

16. Explore the assets directory

The assets directory looks like this:

    assets/
      style.scss

style.scss is the stylesheet for the site.

16.1. About SCSS

style.scss is written in Sassy CSS, which is a superset of CSS. SCSS supports the following two types of comments.

  • /*
       CSS
       multi-line
       comment
    */
  • // SCSS single-line comment

For more about SCSS commenting, see Sass Comments at sass-lang.com. For information about SCSS in general, see Sass (stylesheet language) at wikipedia.org.

In the next section we use SCSS single-line comments.

16.2. Edit style.scss

Open assets/style.scss in a text editor and insert a comment at the top that says something like this:

// 2020-05-29: changed $highlight variable

Next change the $highlight variable to whatever color you would like to use for headers and other highlighted text in the site. I recommend making a backup of the original $highlight setting by commenting out the original line.

style.scss will now look something like this:

// 2020-05-29: changed $highlight variable

// $highlight: rgb(250, 100, 50);
$highlight: blue;

When you save this change, the header colors will immediately change in all pages of http://localhost:1313/.

17. Prepare for publication

When you are ready to publish your site at a web-hosting provider, you will run the hugo command without the server subcommand. This will create the for-publication site files in TGIH/public/.

17.1. Test build without -D or --buildDrafts

In the TGIH directory, run:

hugo server
            👆
            no flag here

In a web browser, view http://localhost:1313/ and make sure that only the files that are ready for publication are built.

If an article is not ready for publication, its front matter should include this:

draft: true

If it is ready for publication, its front matter should include this:

# draft: true

Commenting out the draft key works because draft: false is Hugo’s default. If you prefer, you could change draft: true to draft: false, rather than commenting out the draft key.

💡︎
To list all drafts, run hugo list drafts at a command prompt. Details about the hugo list command are at www.ii.com/hugo-cli/#_hugo_list_help.

 

17.2. Run hugo without subcommands or flags

In the TGIH directory, run:

hugo
     👆
     no subcommands or flags

17.3. Explore the public directory

The hugo command creates a directory named public/ in the TGIH/ directory. If none of the .md files in the content/ directory have draft: true in the front matter, the following will be the structure of this TGIH/public/ directory.

|   index.html
|   index.xml
|   sitemap.xml
|   style.css
|   
+---about
|       index.html
|       
+---articles
|   |   index.html
|   |   index.xml
|   |   
|   +---another-one
|   |       index.html
|   |       
|   +---markdown-experiments
|   |       index.html
|   |       
|   \---one
|           index.html
|           
+---categories
|       index.html
|       index.xml
|       
+---images
|       go-logo_black.png
|       
\---tags
    |   index.html
    |   index.xml
    |   
    +---markdown
    |       index.html
    |       index.xml
    |       
    +---tag1
    |       index.html
    |       index.xml
    |       
    +---tag2
    |       index.html
    |       index.xml
    |       
    \---testtesttest
            index.html
            index.xml
            

 

17.4. Source files, destination files, and pretty URLs

When you build a website with the above hugo command, the files and directories in the static/[25] directory, which are highlighted in the directory tree above, are simply copied to the public/ directory. Non-static files are processed by hugo and their destinations are determined by configuration settings, front matter, and layout files.

The table below shows how some of the TGIH source files are transformed from source to destination to URL (viewable in a web browser after deployment). Some of the TGIH source files are listed in step 4.1 Explore the TGIH directory above.

source in TGIH/destination in
TGIH/public/
URL (if baseURL
is ii.com/)

static/images/go-
logo_black.png

images/go-
logo_black.png

ii.com/images/go-
logo_black.png

assets/style.scss

style.css

ii.com/style.css

content/about.md

about/index.html

ii.com/about/

content/articles/one.md

articles/one/index.html

ii.com/articles/one/

The last two URLs in the URL column above, which are bolded, are called pretty URLs because they do not end with a file extension (.css, .html, .htm, .php, .png, .shtml, etc.).

For more about all this, see:

Note that the above four gohugo.io URLs are “pretty.”

 

17.5. Edit config.yaml again🔧

Open config.yaml in a text editor.

17.5.1. baseURL

The baseURL setting is the bolded line below.

baseURL: https://example.org/
                            👆
                            notice this trailing slash

The slash (/) at the end of the baseURL can’t hurt[20] and sometimes helps, so I recommend that you include it.

When you are really ready to publish — rather than learning Hugo in this Hugo Tutorial: Themeless & Gitless Introduction to Hugo — replace example.org/ with your site’s domain name and path, for example:

  • your.domain.name/

  • your.domain.name/path/to/your/site/

  • your.domain.name/blog/

💡︎

Instead of setting baseURL to https://example.org/ or https://your.domain.name/, you can set it to simply / (slash) like this:

baseURL: /

This makes it easier to publish the site on a test domain and have all the intra-site links work. For example, with this setting the TGIH pages refer to the stylesheet as /style.css rather than https://your.domain.name/style.css.

 

17.5.2. taxonomies🏷️

Above in Step 17.3. Explore the public directory, you can see that the hugo command created directories named categories and tags. These are Hugo’s default taxonomies. Since the TGIH website uses tags but not categories, we can clean things up by specifying the following table[22] in the config.yaml.

taxonomies:
  tag: tags

This overrides Hugo’s default, which is:

taxonomies:
  category: categories
  tag: tags

To learn about taxonomies in Hugo, see gohugo.io/content-management/taxonomies/.

 

17.5.3. Case sensitivity of variables

‼︎
In a Hugo config file, variables, such as baseURL, languageCode, and title, are sometimes case sensitive so I recommend that you specify them using the upper- and lower-case letters that are specified at gohugo.io/getting-started/configuration/.

 

17.6. Rebuild tip

If you use the hugo command to rebuild your site, it overwrites files in the public/ directory, but it does not delete files that are already there that are no longer used. If you publish everything in the public/ directory, people and bots browsing the web may stumble upon these old files.

To delete these old files, do one of the following.

  • Delete the public/ directory before running hugo

  • or use hugo --cleanDestinationDir, which deletes everything in the public/ directory other than the static files.

 

17.7. Useful build flags

In addition to --cleanDestinationDir, which was discussed in the previous step, you may want to use the --minify flag. This flag removes HTML comments and extraneous whitespace characters in the generated HTML files.

You can specify multiple flags like this:

hugo --cleanDestinationDir --minify

More build flags are listed on Infinite Ink’s Hugo CLI page.

18. Publish the site

To publish or deploy the site, copy all the files and directories in the public/ directory to the appropriate directory on your web-hosting provider’s server.

More information about hosting and deployment is at gohugo.io/hosting-and-deployment/.

19. Possible next steps

19.1. Play with the exampleSite from a theme

A good way to learn more about Hugo is to do the following.

  1. Browse themes.gohugo.io and find a theme that you like that includes…

    • an exampleSite directory

    • and a README with clear detailed instructions.

  2. Download the theme and rename its directory so that it includes the date you downloaded it, for example themename-2020-05-29. This is useful if you experiment with a lot of themes on a lot of days over many years (as I have done).

  3. At a command prompt, go to the themename-2020-05-29/exampleSite/ directory and run hugo server -D. Note that you will probably need to edit the config file that is in the exampleSite directory so that the themesDir and theme configuration settings are set to something like the following.

    themesDir: ../..
    theme: themename-2020-05-29

    If the theme’s example site uses a config.toml rather than a config.yaml, change this YAML syntax to TOML syntax.

  4. Follow the directions in the README and experiment with the theme’s files and its example site’s files.

  5. Go to #1 and repeat with another theme.♾️

 

19.2. Learn about Hugo bundles

This tutorial does not explicitly use bundles because I wanted to keep it simple, but when you read the Hugo documentation and play with example sites from themes, you will see files below the content/ directory named index.md and _index.md.[26] A content file with either of these names is a part of a Hugo bundle. To learn about this, see Infinite Ink’s Introduction to Hugo Bundles⁠🎁.

Debugging tips

This section is now on a separate Infinite Ink page called Debugging Your Hugo Website.

Thanks!

Most of the tools and resources that I used to write this article are free/libre open source software (FLOSS). Thank you to the free-culture and open-source movements, and…

Endnotes


1. The TGIH website does not use JavaScript, but the Hugo server uses JavaScript for LiveReload.
2. By “remote” I mean “third-party remotely-hosted.”
3. A command-line interface is sometimes called a CLI, command-line interpreter, command-line shell, console, or terminal.
4. cmd.exe is also known as CMD and is pronounced “cee em dee.” Details are at Wikipedia’s cmd.exe.
5. If you use a “sync app,” such as Dropbox or Sync.com, you may want to put your Hugo directory somewhere in ~/Dropbox or ~/Sync. To learn about these type of apps and services, see wikipedia.org/wiki/File_hosting_service.
6. Using tilde (~) as a shortcut for the home directory works in PowerShell and nix-based shells, but does not work in cmd.exe.
7. Hugo layouts, which are also called templates, are written in Go HTML.
8. I prefer YAML to TOML mainly because I do not want to have to put all “TOML tables” at the bottom of the config.toml file. Instead I want to structure my config file in a way that makes sense to me. Also, using YAML for both front matter and the config file means I only need to remember the syntax of one of these data-serialization formats. Information about YAML is in Infinite Ink’s YAML includes Atoms, Maps, and Lists.
9. To install or update extended hugo.exe on Windows with the Scoop package manager, run scoop install hugo-extended or scoop update hugo-extended at a PowerShell prompt. Details about Scoop’s current hugo-extended version are at github.com/ScoopInstaller/…/hugo-extended.json.
10. The command sudo dpkg --install ./hugo_extended_0.71.1_Linux-64bit.deb will work if you invoke it from the directory that the .deb is in. Since hugo has no dependencies, there should be no issues installing it with dpkg --install. (This is how I install hugo on WSL, formerly known as “Bash on Ubuntu on Windows.”)
11. “Binary” is another word for executable.
12. A nice introduction to pipelines is Jessie Frazelle’s For the Love of Pipes.
13. Windows has many different command-line shells, including cmd.exe, PowerShell, and WSL shells (bash, zsh, etc.). The more pager is built-in to all of these.
14. TGIH (for Themeless & Gitless Introduction to Hugo) will be the “working directory” for the rest of this tutorial.
15. The Unicode name for “dash” (-) is hyphen-minus. Details are at Hyphen-minus - Wikipedia.
16. As of Hugo v0.60.0, which was released on 2019-November-27, Goldmark is the default Markdown parser, the Mmark Markdown parser is deprecated, and it was announced that the Blackfriday Markdown parser will eventually be deprecated.
17. If you want to use upper-case characters in a web page URL, put disablePathToLower: true in your config.yaml.
18. HTML comments will be removed from the built HTML pages if you build with hugo --minify.
19. With Scalable Vector Graphics (SVGs), it is possible to actually include an image in an HTML file by using the <svg> tag. Information about using SVGs, including inline SVGs, is at svgontheweb.com/#implementation.
20. Double slashes in a path will be interpreted as one slash so, for example, https://example.org//images/go-logo_black.png is interpreted as https://example.org/images/go-logo_black.png.
21. The plural of “emoji” can be spelled “emoji” or “emojis.” To learn about pluralizing the word “emoji,” see merriam-webster.com’s definition of emoji and the second Q in emojipedia.org’s FAQ.
22. A nested map is also known as an associative array, a dictionary, a dict, a hash table, a hash, a map, a mapping, a named map, an object, or a table. For more about this data-serialization object, see Infinite Ink’s YAML includes Atoms, Maps, and Lists.
23. If this were a config.toml, rather than a config.yaml, the markup table would need to be placed at the bottom of the config file. I wrote about this on Infinite Ink’s Hugo Fragments and Tips page in Fragment 13 and above in Endnote 8.
24. In Hugo markdownify means convert Markdown to HTML
25. In Hugo, the static directory or directories can be specified with the staticDir parameter in a config file. The default is a single directory named static.

Edit this page👍👎✍

To add a reaction or comment to this page, you need a GitHub account and your browser needs to be able to run a script that is hosted at https://utteranc.es.