TGIH: Themeless & Gitless Introduction to Hugo
a tutorial covering the basics of the Hugo static site generator

 

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

 

Page contents

 

Prerequisites

Background

This Themeless & Gitless Introduction to Hugo assumes that you have experience…​

  • creating simple HTML+CSS web sites

  • and using the command line.

It does not assume anything about what platform and apps (other than Hugo) 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.

Other Tools

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

InterfaceUsed For

command-line interface (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 web site’s archetype, 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, 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

Site development files in home directory

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

  1. most backup apps automatically back up the 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:

    • echo $HOME

  • 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 web site’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, 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

⚠️

Warning

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.59.1/extended windows/amd64 BuildDate: unknown
                                      👆

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

‼︎
Make sure you are using Hugo Extended version 0.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.

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[11] 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 many platforms, including Windows[12] 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 in your home directory. Information about this tip is in Site development files in home directory 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 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-2019-11-17/
  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. 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,

  • or project root.

The Backups/TGIH-2019-11-17/ directory will come into play only if there is a problem with the web site.

4.1.2. 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 is called TGIH: Themeless & Gitless Introduction to Hugo.

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 web site.

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, open http://localhost:1313/. You should see something like this:

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 Web Site.

6. View markdown-experiments.md

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.

6.1. Anatomy

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 TGIH: 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.2. Front matter

The file begins with with three dashes[13] --- 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.3. 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; if the front matter is in JSON format, it is required.

6.4. 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. Meta

7.1. About Hugo’s 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 Blackfriday-flavored markdown.

7.2. About YAML

In Hugo, you can use JSON, TOML, or YAML data-serialization languages in…

  1. site configuration files,

  2. front matter of content 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 filename.

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

  • Use all lower case for directory and file names in the content/ directory because most web servers force URL paths to be all lower case.[14]

  • 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:

👉️

In the Subscript / Superscript section of localhost:1313/articles/markdown-experiments/, you can see that neither the subscript markup (H~2~O) nor the superscript markup (19^th^) is rendered as a subscript (H2O) or a superscript (19th). This is because the Markdown flavor we are using, Blackfriday, does not support these Markdown extensions. Mmark-flavored[15] Markdown supports subscript and superscript markup syntax as you can see on Infinite Ink’s Mmark-Flavored Markdown Experiments.

 

⚠️
It’s possible to lose your mind trying to decide what markup language to use for your writing. Trying most of Hugo’s markup languages is part of why it took me almost three[16] years to decide[17] how to use Hugo to modernize the Infinite Ink site.

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

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

# 2019-11-17: 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.

10.1. About configuring Hugo

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

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

  • in command-line flags

  • in environment variables

  • in multiple files in a config directory

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

To see 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 in your markdown archetype.

---
## 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 will 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 }}
-->

This is a note to self that my readers will not see unless they “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.

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 values of the following keys.

13.1.1. draft key

The beginning of the front matter in most of the content .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 articles 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

13.1.2. date key

The order of the articles listed on the home page (http://localhost:1313/) is based on the date key. 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 key

The front matter includes a subtitle 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; 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 in 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 emoji codes in the Content of at least one of the .md files. For example:

:man_astronaut:
:star:
:woman_astronaut:

These will not be rendered as emoji[21] until the next step (Step 14).

14. Edit config.yaml again

Open config.yaml in a text edtor.

14.1. enableEmoji

Add the following line anywhere[22] in config.yaml.

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:

    👨‍🚀 ⭐ 👩‍🚀

 

💡︎
The code for the emoji that is in this step’s title is :gear:.

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 web site.

15.1. About Hugo layout files

Each Hugo layout file…

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

  • has the extension .html,

  • and can access site variables and page variables.

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

KindUses layout files
baseof.html and…
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 content under the h1 heading, for example the bolded line below:

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

<p>Here are the articles on this site ordered by date.</p>

This added text is written in HTML, which is why it is within the HTML paragraph tags <p> and </p>. (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>.

For more about Hugo layout[7] files, see gohugo.io/categories/templates/.

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.

This is a CSS multi-line comment:

/*
  this is a CSS comment
*/

And this is an SCSS single-line comment:

// this is an SCSS 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:

// 2019-11-17: 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:

// 2019-11-17: 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. Check baseURL

In config.yaml, 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 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 TGIH stylesheet as /style.css rather than https://your.domain.name/style.css.

17.3. Run hugo without subcommands or flags

In the TGIH directory, run:

hugo
     👆
     no subcommands or flags

17.4. Explore the public directory

The hugo command created a directory named public/ in the TGIH/ directory. If none of the files in the content/ directory have draft: true in the front matter, the following is 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.5. Source files, destination files, and pretty URLs

When you build a web site with hugo, the contents of the static/[23] directory, which are bolded 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 layout files, configuration settings, and front matter.

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

source in TGIH/destination in
TGIH/public/
URL (if baseURL
is example.org)

static/images/go-
logo_black.png

images/go-
logo_black.png

example.org/images/go-
logo_black.png

assets/style.scss

style.css

example.org/style.css

content/about.md

about/index.html

example.org/about/

content/articles/one.md

articles/one/index.html

example.org/articles/one/

The last two URLs in the URL column, 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 three gohugo.io URLs are pretty.

 

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 — aka 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/.

Debugging tips

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

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…

See also

Infinite Ink’s #gohugo is a portal to the Hugo world.

Notes

Discussion and feedback


1. The TGIH web site 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 it does not work in cmd.exe.
7. Hugo layouts, which are also called templates, are written in Go HTML and have the file extension .html. Outside of the Hugo world, Go HTML files sometimes use .gohtml, .gohtmltmpl, or .go.html as the file extension.
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 languages. 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.
10. “Binary” is another word for executable.
11. A nice introduction to pipelines is Jessie Frazelle’s For the Love of Pipes.
12. 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.
13. The Unicode name for “dash” (-) is hyphen-minus. Details are at Hyphen-minus - Wikipedia.
14. If you want to use upper-case characters in a web page URL, put disablePathToLower: true in your config.yaml.
15. Mmark-flavored Markdown is one of the markup languages that Hugo supports. Details about it are at github.com/mmarkdown/mmark. The version of Mmark that Hugo uses is documented at miek.nl/2016/march/05/mmark-syntax-document/.
16. I started considering Hugo before 2016-August-24 and I released the Hugo incarnation of the Infinite Ink site on 2019-May-30. This means it took me almost three years to learn Hugo (which I’m still doing) and to try many of Hugo’s themes and markup languages.
17. I tried Markdown (Blackfriday, Mmark, Pandoc, and R Markdown flavors), Org-mode, and AsciiDoc. After a lot of experiments, I’ve chosen Asciidoctor-flavored AsciiDoc as Infinite Ink’s primary markup language.
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 collapsed to one slash so, for example, https://example.org//images/go-logo_black.png is replaced with https://example.org/images/go-logo_black.png.
21. The plural of “emoji” is either “emoji” or “emojis.” To learn about these words, see emojipedia.org and merriam-webster.com.
22. If this were a config.toml, rather than a config.yaml, this enableEmoji line could not be placed anywhere in the file. Instead it would need to be placed above the “TOML tables.”
23. In Hugo, the static directory or directories can be specified with the staticDir parameter in a config file.

Discussion and feedback

Any comment relevant to this page is welcome, including links to your site and suggestions for improving the writing.

View 1 comments and comment form.

To use this comment form, you need a GitHub account and a browser that allows JavaScript on this page.