Web development can be tricky, especially if you want your site to look nice. That’s where Hugo comes in. Hugo is a static site generator (SSG). It takes simple markdown files and converts them into web-ready HTML/CSS/JS using a theme you provide.
Most Linux distributions already have a package for Hugo. It can also be installed using Homebrew or Chocolatey. If you don’t use a package manager, binaries are available for Windows, MacOS, Linux, FreeBSD, and OpenBSD from the Hugo releases page. Check out the install guide for detailed instructions.
Creating a site
Starting a site is easy. To create the Hugo directory structure in the current directory, run
You can choose between YAML, TOML, and JSON for your config file. Change the
-f option accordingly.
This will create the following skeleton:
Configuring the site
config.yaml file is where your site’s main configuration goes.
(If you used a different format, i.e. JSON or TOML, change the extension accordingly)
There are some basic options that apply to (almost) every Hugo site. The theme you choose in the next step may have extra options to choose from. For a list of all default options, see here.
config.yaml file for this site:
baseURL: The URL where your site will be published
languageCode: the default site language
title: The title of the entire site
author: The site author. Multiple can be specified.
theme: Theme to use (see next step).
enableEmoji: Whether to convert emoji codes to emojis (e.g.
:smile: → 😄)
enableGitInfo: For hugo sites versioned with Git, use the commit date as the ’last modified’ time for each page.
enableRobotsTXT: Generate a
Choosing a theme
Once you find the theme you want, place it into the
If you are using Git to version your Hugo site, you can include your theme as a submodule.
To use the theme in your site, set the
theme key in your configuration file.
For example, if your theme is located in
themes/my-sweet-theme, your config file would contain this line:
Be sure to check if your theme has any extra options to configure.
Page content goes in the
Hugo makes it easy to create a new page:
This will create
If you take a look in the file you’ll notice a header with some variables.
This is called ‘front matter’.
See here for a more complete guide.
A basic page will have something like the following:
date are self-explanatory, but
draft is a bit more complicated.
It controls whether the page gets published in the final site.
Drafts are not included by default when compiling/generating or serving (next step) your page, although that can be changed using some command-line options.
false when you’re done editing a page to ensure it gets published.
Add some filler text below the front matter. We’ll come back to the content later, but for now, let’s turn this into a website.
Serving your website locally for testing
Now that you have a basic page set up, it’s time to transform it into a website:
will start a web server on port 1313.
-D option tells it to include drafts.
This is useful for testing.
Running this will output a URL that you can visit in your browser.
I recommend using a multiplexer like tmux to run your Hugo server when testing. This way you can leave the server running in the background. The Hugo server will automatically update when pages, themes, templates, or configuration files are changed, so leaving it running while editing pages is really handy.
A note on page locations
As you may have noticed, Hugo created a home page, which is a type of list page. Even though you didn’t tell it to, it creates one for the
content folder and all immediate children.
article.md file became
You can set the
uglyurls option to
true in your config file, which will change the behaviour and create
<server url>/article.html instead.
You can create subfolders inside of content, too. Try creating a page using
This would end up as
<server url>/blog/post-1/ in the final website.
If you create more pages under
content/blog/ and then go to
<server url>/blog/, you’ll notice that it is a list page containing all the pages in the
Hopefully you now have a basic understanding of content pages and list pages.
Back to content
Markdown vs HTML
You can choose to use markdown or HTML for your content. Markdown is easier, but HTML gives more control. However, markdown lets you embed HTML, so in my opinion, it’s superior. This way you have both the ease of markdown and the control of HTML in a single file.
There are lots of tutorials on markdown, so I’ll refer you to the Hugo docs page about it instead of explaining it here.
Hugo has another great feature called ‘shortcodes.’ These are like shortcuts you can put in your markdown files. They make embedding content easier. I’ll go over two of them, but the full list is located here.
A figure is some content (usually an image) and an optional caption. To create a captioned image using Hugo, use this shortcode:
image.png in the
static folder, and you’re all set.
Well, there’s a catch. If your site is located at a path like
<server url>/blog/, you’ll have to account for that in your
src field. So you’d end up with the following:
It’s super easy to include syntax-highlighted text, usually code, in a Hugo site. Just use the
As you can see, the second
highlight shortcode is prefixed with a slash (
/) to indicate that it closes a previous one, just like HTML tags.
Generating the website
You could serve your website using
hugo server, but you probably want to create static content.
To compile your website, run
If you want to include draft pages, add the
This will put your compiled content in the
You change this by setting the
publishDir option in your configuration file.
will put the compiled content in the directory above your hugo directory.
I do this with my website, so I can have a
hugo folder that gets ignored by the web server, while the content stays accessible in the parent directory.
Hopefully you now know how to create a basic hugo site. Be sure to read the Hugo documentation, which covers everything you could wonder about Hugo. I also recommend taking a look at the official getting started guide, which is slightly more in-depth than this guide.