How to Use Taxonomies in Hugo
Taxonomies are Hugo’s system for classifying and grouping content. Used well, they provide the structural backbone of a publishing site — the navigation paths, archive pages, and content relationships that let readers move through a site meaningfully. Hugo’s taxonomy system is flexible and powerful, but it requires deliberate configuration to use effectively.
What Hugo’s Taxonomy System Does
A taxonomy is a classification dimension. Tags and categories are the two built into Hugo by default, but you can define any number of custom taxonomies — series, authors, topics, formats, locations — and Hugo will generate archive pages and RSS feeds for each.
When you assign a post to a taxonomy term, Hugo automatically:
- Adds the post to that term’s listing page
- Creates a page for the term if it does not already exist
- Generates an RSS feed for the term
- Provides template variables to display related content
This all happens without any database or plugin. It is derived from the frontmatter in your content files at build time.
Default Taxonomies
Hugo ships with tags and categories pre-configured. You do not need to add anything to hugo.toml to use them. In your frontmatter:
---
title: "My Post"
date: 2026-04-29
draft: false
tags: ["publishing", "cms", "workflow"]
categories: ["Guides"]
---
Hugo generates:
/tags/— list of all tags/tags/publishing/— all posts tagged “publishing”/tags/publishing/index.xml— RSS feed for that tag/categories/guides/— all posts in the Guides category
Defining Custom Taxonomies
Add custom taxonomies in hugo.toml. When you define custom taxonomies, you must also re-declare the defaults if you want to keep them:
[taxonomies]
tag = "tags"
category = "categories"
series = "series"
author = "authors"
topic = "topics"
Note the singular/plural pattern: the key is singular (author), the value is plural (authors). The plural form is the frontmatter key and the URL segment.
Now you can use these in frontmatter:
---
title: "The Future of Independent Publishing"
date: 2026-04-29
draft: false
tags: ["indie publishing", "media"]
series: ["Publishing Industry Trends"]
authors: ["Jane Smith"]
topics: ["business models", "journalism"]
---
Taxonomy Pages and Templates
Hugo looks for taxonomy templates in layouts/ following a specific lookup order. For the tags taxonomy:
layouts/tags/list.html— the page listing all posts for a specific taglayouts/taxonomy/tag.html— fallbacklayouts/_default/list.html— final fallback
For the taxonomy index (the page listing all tags):
layouts/tags/terms.htmllayouts/taxonomy/terms.htmllayouts/_default/terms.html
A basic tag list template:
{{ define "main" }}
<h1>Posts tagged: {{ .Title }}</h1>
{{ range .Pages }}
<article>
<h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
<time>{{ .Date.Format "January 2, 2006" }}</time>
<p>{{ .Summary }}</p>
</article>
{{ end }}
{{ end }}
Ordering and Filtering in Taxonomy Pages
Taxonomy pages expose their content through the .Pages variable. You can sort and filter:
{{/* Sort by date, newest first */}}
{{ range .Pages.ByDate.Reverse }}
{{/* Limit to 10 most recent */}}
{{ range first 10 .Pages.ByDate.Reverse }}
{{/* Sort alphabetically */}}
{{ range .Pages.ByTitle }}
Adding Metadata to Taxonomy Terms
Taxonomy terms can have their own content pages with frontmatter, descriptions, and custom fields. Create a content file matching the taxonomy term path:
content/
tags/
publishing/
_index.md
In _index.md:
---
title: "Publishing"
description: "Articles covering the publishing industry, tools, and trends."
featured_image: "/images/tags/publishing.jpg"
---
An introductory paragraph that appears on the tag archive page.
The term page template can then access .Params, .Content, and .Description from this file, allowing rich landing pages for important taxonomy terms.
Displaying Taxonomy Terms on Posts
In a single post template, access the post’s taxonomy terms:
{{/* Display tags */}}
{{ with .Params.tags }}
<div class="tags">
{{ range . }}
<a href="{{ "/tags/" | relURL }}{{ . | urlize }}/">{{ . }}</a>
{{ end }}
</div>
{{ end }}
{{/* Display all taxonomies */}}
{{ range $taxonomy, $terms := .Params }}
{{ if ($.Site.GetPage "taxonomyTerm" $taxonomy) }}
{{ range $terms }}
<a href="/{{ $taxonomy | urlize }}/{{ . | urlize }}/">{{ . }}</a>
{{ end }}
{{ end }}
{{ end }}
Related Content via Taxonomies
Hugo has a built-in related content system that uses taxonomies to find related posts. Configure it in hugo.toml:
[related]
includeNewer = true
threshold = 80
toLower = false
[[related.indices]]
name = "tags"
weight = 100
[[related.indices]]
name = "series"
weight = 80
[[related.indices]]
name = "date"
weight = 10
In your single post template:
{{ $related := .Site.RegularPages.Related . | first 3 }}
{{ with $related }}
<h3>Related Posts</h3>
{{ range . }}
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
{{ end }}
{{ end }}
Taxonomy Configuration Tips
A few patterns that save time:
Consistent term naming. Hugo normalizes taxonomy terms to lowercase for URL generation but displays them as written. Decide on a consistent capitalization convention and stick to it — “Web Publishing” and “web publishing” will both route to /tags/web-publishing/ but appear differently in listings.
Limit taxonomy count. More taxonomies means more archive pages and more template surface area. Start with the ones you actually need. You can always add more later; pruning is harder.
RSS per term. Hugo generates RSS feeds for every taxonomy term automatically. These are genuinely useful for readers who want to subscribe to specific topics. Make sure your theme exposes them in link tags.