Add Tags to Your Hugo Blog Using Taxonomies
Since the inception of this blog, I've wanted to add "tags" to my posts. Readers could then browse a list of related posts based on a specific tag. Using Hugo's nifty taxonomies feature, I was able to easily built out that functionality.
Taxonomies are used to define relationships between your content. tags
is an
example of a taxonomy. In fact, it is also one of the
two default taxonomies
that Hugo supports out-of-the-box. 📦
Configuring the tags
taxonomy
Because the tags
taxonomy is a Hugo default, the necessary site configuration
is practically non-existent. You don't need to adjust your config at all. In my
case, I had no plans of using the other default taxonomy, categories
, so I
took
an additional step to remove it.
This is not necessary.
If you wish to define your own taxonomy rather than use one of the defaults, refer to the Hugo docs .
Defining tags
in your blog posts
Now that your site is properly configured to support the tags
taxonomy, it's
time to actually define some in your posts. This is done in the front matter of
your post's content file:
---
title: 'A Blog Post'
tags: ['value_1', 'value_2']
---
"value_1"
and "value_2"
are individual tags. The post above will form a
relationship with any other post that shares one of these tags.
One of the main goals I wanted for this blog was to have dedicated pages for each tag. These pages would then render a list of posts that all have that tag in common. This creates a better experience for the reader, giving them the ability to browse related posts.
Luckily, Hugo creates these list pages for each taxonomy value you define, even if they are only used once. Using the example above, list pages will be created at:
/tags/value_1
/tags/value_2
In order for actual content to be rendered on these pages, we'll need to define a special template.
Taxonomy list templates
Hugo uses templates to render content, and these templates reside in the
layouts/
directory. With taxonomies this is no different.
Using a taxonomy list template, you can render a list of blog posts that share the same tag. The lookup order for these templates can get a little confusing. There are a number of naming conventions and file placements you can use.
I achieved this by creating a layouts/taxonomy
directory, and inside of that
directory a tag.html
file:
layouts/
taxonomy/
tag.html
Using the example from the last section, tag.html
will be the list template
that Hugo uses to render the /tags/value_1
and /tags/value_2
pages.
The following markup can be used in the list template to render posts with related tags:
<ul>
{{ range .Data.Pages }}
<li>
<a href="{{.RelPermalink}}">{{ .Title }}</a>
</li>
{{ end }}
</ul>
Now, if you go to the /tags/value_1
page, you should see a list of blog posts
that all contain the tag "value_1"
. 😆
Render tags in content pages
The last feature I want to support is listing all of the tags for a specific blog post on that post's page. This took a little bit of digging to figure out.
First, create a new partial template in
layouts/partials
called tags.html
. Add the following markup to the file:
{{ $taxonomy := "tags" }} {{ with .Param $taxonomy }}
<ul>
{{ range $index, $tag := . }} {{ with $.Site.GetPage (printf "/%s/%s"
$taxonomy $tag) -}}
<li>
<a href="{{ .Permalink }}">{{ $tag | urlize }}</a>
</li>
{{- end -}} {{- end -}}
</ul>
{{ end }}
The code above will check to see if tags
are defined for a given post. If they
are, the tags will be rendered in an unordered list, with a link to each tag's
list page (i.e. /tags/value_1
).
Now, you can add this partial template to your blog's single page template. Mine
is defined at layouts/blog/single.html
:
<!-- ... -->
{{ partial "tags.html" .}}
With that, all of your blog posts will render a list of their tags
if they are
defined.
Preserving taxonomy values
One little gotcha about taxonomy values in Hugo is that their names are
normalized. To preserve the values that you explicitly define, you can
add a special option
to your site's configuration called preserveTaxonomyNames
and set it equal to
true
.
Conclusion
The examples above should get you up and running with a simple tags setup for your Hugo-powered blog. The template markup contains simple list elements with anchor links, and I've purposefully left out any styling suggestions.
90% of the information found in this post can be applied to custom taxonomies as well. The only difference is that you will need to define the taxonomy in your site's configuration and adjust the naming of your taxonomy list template.