Following Gradients
A blog of math and marmots


Hugo Basic Concepts

Note: These are incomplete personal notes and unlikely to be generally useful

Hugo creates pages by filling in templates with content. A template is exactly a Go html template. It can make use of other templates, configuration (defined in config.toml, front matter, or data files), and Hugo-specific variables that contain information about the organization of the site as a whole. Content is written in Markdown, with an extention that allows the use of shortcodes. A shortcode is a template that can be called, with parameters, from within Markdown. This template will be fully expanded when rendered. Static files (like images, js, and css) belong in the static/ directory. Hugo does not provide js/css build tools, but it is easy enough to use another build tool like Gulp or Webpack where static/ is the output directory.


Content consists of markdown files in the content/ directory. Each content file typically contains front matter where metadata specific to this content is defined. Content files are typically created with hugo new, which initializes the front matter. The default URL for the content will match the path under the content/ directory, followed by index.html. (eg. /posts/my-first-post/index.html). Of course, browsers will not need the index.html. This can all be configured with front matter.

Three important properties of content are the section, the type, and the layout. The section is defined by the location of the content under the content/ directory. Sections will follow the directory hierarchy as long as every directory below the root level contains (at the deepest level) an file. The easiest thing is just to use first-level directories, which don’t require an, and are referred to as root sections. As a matter of convention, section names are often plural.

The type of a content file can be defined in front matter. By default, it is the same as the root section of the file. The type is used to select the template (see the layouts section below for more on this). As a matter of convention, type names are often singular. So articles would be a common section name and article would be a type name.

Much more to say here about files, and including resources (like images) on specific pages.


Archetypes control the front matter that is created by hugo new. The are based on a section (TODO: can this also be based on a type?) and have the name archetypes/<SECTION NAME>.md.


Layout is written in Go’s HTML templating format, and the files live in the layout/ directory. Two important issues to understand are what template is used for a given piece of content, and the names and scoping of the variables that the template has available.

The sane default for the first issue is that the top-level path component under content/ will look for a single.html file in a parallel directory under layouts/. So, for example, content/articles/.../ will be styled by the template in layouts/articles/single.html by default. Much configuration is possible here, across two different dimensions, section and type.

Templates that should be defined for even a minimal example are the homepage template, and at least one single page template. Other useful template examples are list page templates, specific section templates, content view templates (useful generating different views of the same content, which can then be embedded in other higher-level templates), and partial and short code templates (which essentially define “template functions” that can be used elsewhere).

In order to prevent repetition of boilerplate, it is useful to use a base template. This should live at layouts/_default/baseof.html and look something like this:

<!DOCTYPE html>
    {{ block "head" . }}
    {{ end }}
    {{ block "nav" . }}
    {{ end }}
    {{ block "main" . }}
    {{ end }}
    {{ block "footer" . }}
    {{ end }}

The blocks themselves can contain default values or not (don’t use literal ...). These blocks can be defined / overwritten at whatever level of scope makes sense in a another template. So, for example, layouts/_default/single.html will just look like:

{{ define main }}
  <!-- Templated html goes here -->
{{ end }}
Any page that uses this template will get the baseof template, with only the main block from this file.

A subtle point is the difference between partial templates and shortcode templates. The main difference is that partials are invoked from other templates, and shortcodes are invoked from content. Partials accept a single context argument, often this is . which refers to the current context of the caller. Shortcodes have flexible, configurable arguments. See this discussion for more context.