Introduction to Hugo Bundles⁠🎁
Updated  2023-March-16

Page contents

News

2022-April-28  As of today, this evolving⁠[1] article has been on the web for 2 years.🎂🎂

Prerequisites

This article assumes you know how to use Hugo to generate web pages from source files that are not bundles. One way to learn about that is in Infinite Ink’s TGIH: Themeless & Gitless Introduction to the Hugo SSG (a Hugo tutorial). Here is part of that tutorial’s content directory, along with some Hugo terminology:

TGIH/content.Kind[2]Also Known As

/

home

List Page

/about.md

page

Regular Page

/articles/

section

List Page

/articles/one.md

page

Regular Page

Note that…

  • None of the TGIH content files and directories are bundles.

  • Some TGIH content files and directories are converted to bundles in the examples below.

  • Since Hugo v0.18, which was released 2016-December-19, “every piece of content is a Page.”

 

What is a Hugo bundle?

A source file below the content/ directory named either index.md or _index.md means that hugo will generate the destination file(s) from some or all of the files in a directory. When index.md is used, the containing directory is called a leaf bundle and when _index.md is used, the containing directory is called a branch bundle.

  • A leaf bundle is also known as a single page or a Regular Page.

  • A branch bundle is also known as a List Page.

 

Leaf bundles

Two examples without resources

Step 17.4[3] in Infinite Ink’s Hugo Tutorial discusses the transformation of some TGIH files from source to destination to URL (viewable in a web browser after deployment). Here is a modified version of that transformation table.

Transformation of non-bundles

source in
TGIH/content/

about.md

articles/one.md

destination in
TGIH/public/

about/index.html

articles/one/index.html

URL (if baseURL
is ii.com/)[4]

ii.com/about/

ii.com/articles/one/

An equivalent alternative is to replace about.md with about/index.md and replace articles/one.md with articles/one/index.md. The transformations then looks like this:

Transformation of leaf bundles

source in
TGIH/content/

about/index.md

articles/one/index.md

destination in
TGIH/public/

about/index.html

articles/one/index.html

URL (if baseURL
is ii.com/)[4]

ii.com/about/

ii.com/articles/one/

With this structure, the source directories content/about/ and content/articles/one/ are each a leaf bundle.

 

Example with a resource

The source of this article is an example of a leaf bundle with a page resource. Here are the details.

If a leaf bundle looks something like this…

.
└── hugo-bundles/
    ├── index.md
    └── hgopher.svg

…then you can use the following Markdown image syntax in index.md to reference the image.

![Hugo Gopher](hgopher.svg)
               -----------
                    👆
               path relative to index.md

 

With the above source directory structure, Hugo will generate a destination directory structure and HTML code that a web browser will display like this web page, including the following image:

Hugo Gopher

 

💡
  • For a relative path like this to work, the image usually must be part of a Hugo bundle.

  • In a leaf bundle (but not in a branch bundle), it’s OK to put resources in a subdirectory of the leaf bundle. For example, if content/hugo-⁠bundles/img/hgopher.svg exists, then using !⁠[Hugo Gopher]⁠(img/hgopher.svg) in index.md will work.

 

 

Tip: How to use hugo new to create a leaf bundle

If ROOT/archetypes/default.md exists, you can use a command like the following to create a new leaf bundle:

hugo new articles/directory-name/index.md
                  --------------
                        👆
                  used as .Name in archetype’s Go HTML

To learn about Hugo archetypes, see step 11. Edit the archetype for new .md content files in Infinite Ink’s Hugo Tutorial.

 

Branch bundle example

In step 15 in Infinite Ink’s Hugo Tutorial, I wrote about adding content to the TGIH home page, which is a List Page, by adding the following highlighted HTML paragraph to the home.html[5] layout file.

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

<p>
Here are the articles on this website <strong>ordered by publication date</strong>, starting with the most recently published article.
</p>

 

An alternative is to put the following highlighted line in home.html.

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

{{ .Content }}

 

And create content/_index.md that contains the following.

---
# front matter, possibly empty, is required
---

Here are the articles on this website **ordered by publication date**, starting with the most recently published article.

 

The content/ directory is an example of a branch bundle and this content/_index.md file contains metadata (essentially empty in this case) and Markdown content for the home page. The transformation will look like this:

Transformation of a branch bundle

source in
TGIH/content/

_index.md

destination in
TGIH/public/

index.html

URL (if baseURL
is ii.com/)[4]

ii.com/

Note that if this _index.md file does not exist, the home page is created entirely from the TGIH layouts/_default/home.html layout file, which references some config settings, such as the title site variable.

 

Bundle metaphors

In this section I describe some metaphors I use to remember the meanings of _index.extension and index.extension.

I remember the meaning of _index.extension by imagining that the leading underscore (_) is one or more of these:

  • a fragment of capital letter L, which reminds me that _index is used for a List Page

  • a doorway that allows Hugo to enter and process any child page — either a child Regular Page or a child List Page — within this directory🚪

  • a tree branch or plant branch that may comprise multiple leaves and/or multiple sub-branches⁠🌿

I remember the meaning of index.extension by noting that there is no doorway or branch (i.e., no _) and Hugo will process this directory as a Regular Page.

 

Bundle references

See also

Endnotes


1. Many Infinite Ink articles, including this one, are evergreen and regularly updated.
2. .Kind is a built-in Hugo page variable and some of the possible values of this variable (for example “term”) changed in v0.73.0. To learn about this, see the Hugo v0.73.0 release notes and the tip in the Taxonomies section of Infinite Ink’s Hugo Tutorial.
3. Step 17.4 in Infinite Ink’s Hugo Tutorial is also available as a standalone page at Hugo Source Files, Destination Files, and Pretty URLs (thanks to an AsciiDoc include directive).
4. This is the URL if the output of the hugo config command includes uglyURLs: false, which is the default, and baseURL: ii.com/.
5. The home page layout file can be named either home.html or index.html. I prefer to name it home.html because the word index is semantically overloaded in Hugo.

Discuss or share 📝 🤔 🐘