Configure related content
Use the Pages.Related method to render related content in your templates.
Hugo provides a sensible default configuration for identifying related content, but you can customize it in your project configuration, either globally or per language.
Default configuration
This is the default configuration:
related:
includeNewer: false
indices:
- applyFilter: false
cardinalityThreshold: 0
minTokenLength: 0
name: keywords
pattern: ''
toLower: false
tokenize: false
type: basic
weight: 100
- applyFilter: false
cardinalityThreshold: 0
minTokenLength: 0
name: date
pattern: ''
toLower: false
tokenize: false
type: basic
weight: 10
- applyFilter: false
cardinalityThreshold: 0
minTokenLength: 0
name: tags
pattern: ''
toLower: false
tokenize: false
type: basic
weight: 80
threshold: 80
toLower: false
[related]
includeNewer = false
threshold = 80
toLower = false
[[related.indices]]
applyFilter = false
cardinalityThreshold = 0
minTokenLength = 0
name = 'keywords'
pattern = ''
toLower = false
tokenize = false
type = 'basic'
weight = 100
[[related.indices]]
applyFilter = false
cardinalityThreshold = 0
minTokenLength = 0
name = 'date'
pattern = ''
toLower = false
tokenize = false
type = 'basic'
weight = 10
[[related.indices]]
applyFilter = false
cardinalityThreshold = 0
minTokenLength = 0
name = 'tags'
pattern = ''
toLower = false
tokenize = false
type = 'basic'
weight = 80
{
"related": {
"includeNewer": false,
"indices": [
{
"applyFilter": false,
"cardinalityThreshold": 0,
"minTokenLength": 0,
"name": "keywords",
"pattern": "",
"toLower": false,
"tokenize": false,
"type": "basic",
"weight": 100
},
{
"applyFilter": false,
"cardinalityThreshold": 0,
"minTokenLength": 0,
"name": "date",
"pattern": "",
"toLower": false,
"tokenize": false,
"type": "basic",
"weight": 10
},
{
"applyFilter": false,
"cardinalityThreshold": 0,
"minTokenLength": 0,
"name": "tags",
"pattern": "",
"toLower": false,
"tokenize": false,
"type": "basic",
"weight": 80
}
],
"threshold": 80,
"toLower": false
}
}
Adding a related section to your project configuration requires you to provide a full configuration. You cannot override individual default values without specifying all related settings.
Top-level settings
threshold- (
int) A value in the range[0, 100]. A lower value will return more, but maybe not so relevant, matches. includeNewer- (
bool) Whether to include pages newer than the current page in the related content listing. The output for older posts may change as new related content is added. Default isfalse. toLower- (
bool) Whether to transform keywords in both the indexes and the queries to lower case. This may give more accurate results at a slight performance penalty. Default isfalse.
Per-index settings
applyFilter- (
bool) Apply atypespecific filter to the result of a search. This is only used for thefragmentstype. Default isfalse. cardinalityThreshold- (
int) The percentage threshold, in the range[1, 100], above which indexed values are removed from the index. For example, a value of60removes all indexed values that appear in more than 60% of the documents. A value of0disables filtering. Default is0. minTokenLength- New in v0.166.0
- (
int) Whentokenizeistrue, the minimum token length in Unicode code points. Use this to exclude short words such asa,in, andthe, regardless of their frequency. This setting is applied beforecardinalityThreshold, so excluded tokens never enter the index. Default is0, meaning no minimum. name- (
string) The index name. This value maps directly to a page parameter. Hugo supports string values such asauthor, lists such astagsandkeywords, and time and date objects. pattern- (
string) This is only relevant for dates. When listing related content, you may want to list content that is also close in time. Setting2006, the default value for date indexes, as the pattern for a date index will add weight to pages published in the same year. For busier blogs,200601, representing year and month, may be a better default. tokenize- New in v0.166.0
- (
bool) Whether to tokenize string values by splitting on whitespace before indexing.For indices of type
fragments, non-heading fragments such as description list terms are always indexed by their exact identifier.Tokenizing increases index size in proportion to the number of words per value. Consider setting
minTokenLengthto exclude short words andcardinalityThresholdto remove high-frequency words from the index.Singular and plural forms such as
appleandapplesare treated as distinct words, and CJK languages and other scripts without whitespace word boundaries are not supported.Default is
false. toLower- (
bool) Whether to transform keywords in both the indexes and the queries to lower case. This may give more accurate results at a slight performance penalty. Default isfalse. type- (
string) One ofbasicorfragments. Default isbasic. weight- (
int) An integer weight that indicates how important this parameter is relative to the other parameters. It can be0, which has the effect of turning this index off, or even negative. Test with different values to see what fits your content best. Default is0.
Examples
The following examples demonstrate common configuration patterns.
Related by taxonomy terms
Imagine we’re building a book review site. Our main content will be book reviews, and we’ll use genres and authors as taxonomies. When someone views a book review, we want to show a short list of related reviews based on shared authors and genres.
Create the content:
content/
└── book-reviews/
├── book-review-1.md
├── book-review-2.md
├── book-review-3.md
├── book-review-4.md
└── book-review-5.mdConfigure the taxonomies:
taxonomies:
author: authors
genre: genres
[taxonomies]
author = 'authors'
genre = 'genres'
{
"taxonomies": {
"author": "authors",
"genre": "genres"
}
}
Configure the related content identification:
related:
includeNewer: true
indices:
- name: authors
weight: 2
- name: genres
weight: 1
threshold: 80
toLower: true
[related]
includeNewer = true
threshold = 80
toLower = true
[[related.indices]]
name = 'authors'
weight = 2
[[related.indices]]
name = 'genres'
weight = 1
{
"related": {
"includeNewer": true,
"indices": [
{
"name": "authors",
"weight": 2
},
{
"name": "genres",
"weight": 1
}
],
"threshold": 80,
"toLower": true
}
}
We’ve configured the authors index with a weight of 2 and the genres index with a weight of 1. This means Hugo prioritizes shared authors as twice as significant as shared genres.
Then render a list of 5 related reviews with a partial template like this:
{{ with site.RegularPages.Related . | first 5 }}
<p>Related content:</p>
<ul>
{{ range . }}
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
{{ end }}
</ul>
{{ end }}Related by title words
Imagine we’re building a blog. We want to show related posts based on shared words in the title. For example, a post titled “Hugo image processing” should match any post whose title contains Hugo, image, or processing.
Configure the related content identification:
related:
indices:
- minTokenLength: 4
name: title
tokenize: true
weight: 1
threshold: 50
toLower: true
[related]
threshold = 50
toLower = true
[[related.indices]]
minTokenLength = 4
name = 'title'
tokenize = true
weight = 1
{
"related": {
"indices": [
{
"minTokenLength": 4,
"name": "title",
"tokenize": true,
"weight": 1
}
],
"threshold": 50,
"toLower": true
}
}
With tokenize set to true, Hugo splits each page title on whitespace and indexes the individual words. Setting minTokenLength to 4 excludes short words such as and, the, and for. Then use the same partial template shown in the previous example to render the results.
