Comment Créer Un Site Avec Hugo Partie 7 : ajouter des liens de contenus en relation

Aldok

| 6 minutes

Revenir à l'index du tuto : Creer un site avec hugo

Mise à jour — Mai 2026

Ce tutoriel a été intégralement révisé pour rester à jour avec Hugo 0.161 et les outils modernes de l'écosystème (Bulma 1.x, vanilla JS, Netlify Forms, OpenStreetMap, Giscus...). Les anciennes syntaxes dépréciées sont signalées quand c'est utile pour comprendre l'évolution.

Créer un site avec Hugo partie 7 : ajouter des liens de contenus en relation

Vous aurez sûrement remarqué que la plupart des blogs intègrent une fonction qui permet de promouvoir d’autres articles en relation avec l’article en cours, et de manière souvent plus intelligente que ce qu’on peut rencontrer ailleurs.

Hugo propose cette fonctionnalité nativement : on va voir comment l’implémenter dans notre template fait main.

Comment ça fonctionne concrètement ?

Hugo va associer les articles qui ont une taxonomie commune : c’est donc au niveau du frontmatter de chaque article qu’il va falloir faire un travail de catégorisation.

La page dédiée à la documentation du contenu relatif se trouve ici : https://gohugo.io/content-management/related/

Comment configurer les pages liées ?

Quand on regarde la configuration par défaut de la fonction d’affichage des contenus liés, voici ce qu’elle contient (en YAML) :

related:
  threshold: 80
  includeNewer: false
  toLower: false
  indices:
  - name: keywords
    weight: 100
  - name: date
    weight: 10

Voyons en détail à quoi correspondent ces données de configuration.

threshold: 80

Cette ligne indique un seuil de similarité à 80/100 (on va dire 80 % pour simplifier) ; plus la valeur indiquée est élevée, plus l’accent sera mis sur les contenus les plus similaires, quitte à ne rien afficher du tout si aucun article ne correspond assez.

À l’inverse, plus la valeur sera faible, et moins on sera “select” sur les contenus à afficher. En mettant 0, on affichera un article en relation même s’il ne colle pas avec la thématique de l’article en cours.

includeNewer: false

En mettant false, on indique qu’on ne veut pas que s’affichent des articles avec une date plus récente que l’article affiché. En mettant true, on autorise donc l’affichage d’articles plus récents.

toLower: false

En mettant true, on demande à Hugo de mettre les mots-clés en minuscules pour éviter les éventuelles erreurs de casse qui pourraient créer des doublons (par exemple “Blogging” et “blogging” considérés comme deux taxonomies différentes).

indices:

Ce qui suit ce terme fait tout le “sel” de la fonction related : on va pouvoir définir une sorte d’algorithme qui va trier automatiquement le contenu en fonction des critères qui nous semblent les plus pertinents.

Cela signifie que Hugo va d’abord chercher une liste de mots-clés (keywords) dans le frontmatter de chaque page, et va lier entre elles les pages qui partagent le plus de mots-clés en commun. Il va également utiliser dans une moindre mesure le paramètre relatif à la date.

Les keywords sont un paramètre du frontmatter que nous n’avons pas encore vu, mais il est possible de l’utiliser au même titre que categories.

En d’autres termes, l’algorithme tel qu’il est configuré par défaut va donner un poids de 100 (sur 100) aux mots-clés que les différents articles auront en commun, et un poids de 10 (toujours sur 100) à la date.

Customiser cette fonction

Pour personnaliser cette configuration par défaut, il suffit de se rendre dans hugo.toml et de faire quelques modifs (notez la différence de syntaxe, on passe du YAML au TOML !) :

[related]
    threshold = 80
    includeNewer = true
    toLower = true

    [[related.indices]]
        name = "categories"
        weight = 100

    [[related.indices]]
        name = "date"
        weight = 10

Mon petit côté SEO me dit qu’il vaut mieux ne rien afficher en relation si les thématiques ne sont pas similaires, c’est pourquoi je laisse 80 comme seuil de similarité acceptable.

Par contre, j’aimerais bien que le script affiche aussi les contenus les plus récents, ça serait dommage de rester figé sur les articles les plus anciens. D’autant que si ça peut filer un coup de pouce à l’indexation des nouveaux articles, ce n’est pas de refus !

J’ai mis toLower à true pour éviter les doublons de casse.

Pour ce qui est des indices, j’ai remplacé keywords par categories pour ne créer des relations qu’entre pages de la même catégorie (histoire de rester dans une logique de silos thématiques). L’indice keywords peut être très utile s’il est bien utilisé (un peu comme les tags dans WordPress), mais restons simples et évitons le plat de spaghettis.

L’implémentation du contenu relatif dans le thème

Passons aux choses sérieuses : l’intégration des articles dans le template des pages.

Pour créer un template de contenu relatif, on va s’appuyer sur les partials et créer le fichier suivant :

themes/sandbox/layouts/partials/widgets/post-card-small.html

Voici son contenu :

{{ $permalink := .Permalink }}
<div class="card">
    <div class="card-image">
        <figure class="image is-3by2">
            {{ with .Params.images }}
            <a href="{{ $permalink }}"><img src="{{ index . 0 }}" alt="Illustration de l'article"></a>
            {{ end }}
        </figure>
    </div>
    <div class="card-content">
        <a class="title is-5" href="{{ .Permalink }}">{{ .Title }}</a>
        <span class="heading">
            <time datetime="{{ .PublishDate.Format "2006-01-02" }}">{{ time.Format ":date_long" .PublishDate }}</time>
        </span>
    </div>
</div>

Ensuite, on va l’intégrer dans le template themes/sandbox/layouts/blog/single.html, juste avant la fin du template marquée par le {{ end }} final :

<section class="section">
    <div class="columns is-centered">
        <div class="column max-800px">
            <div class="content">
                <h2>Vous devriez également aimer ce qui suit...</h2>
            </div>
            <div class="columns">
                {{ $related := (where (.Site.RegularPages.Related .) "Type" "blog") | first 3 }}
                {{ range $related }}
                <div class="column is-one-third">
                    {{ partial "widgets/post-card-small.html" . }}
                </div>
                {{ end }}
            </div>
        </div>
    </div>
</section>

Je ne vais pas m’attarder sur l’apparence et la gestion du HTML avec Bulma. C’est plutôt la ligne suivante qui retient notre attention :

{{ $related := (where (.Site.RegularPages.Related .) "Type" "blog") | first 3 }}

Qu’est-ce qu’elle nous dit précisément ?

  • .Site.RegularPages.Related . appelle toutes les pages liées à la page en cours (le . à la fin signifie “le contexte courant”, soit la page actuelle).
  • where ( ... ) "Type" "blog" filtre pour ne garder que les pages dont le type correspond à “blog”. Ça évite de retrouver les pages “à propos” ou “contact” dans les suggestions.
  • | first 3 prend les 3 premiers éléments de la liste résultante (les 3 plus pertinents selon l’algorithme related).
  • {{ $related := ... }} stocke le résultat dans une variable $related qu’on utilise ensuite dans la boucle range.

La petite touche finale

Pour que les différents encarts aient la même hauteur (sinon les colonnes deviennent disgracieuses dès qu’un résumé est plus long qu’un autre), ajoutez ceci à votre feuille de styles :

.card {
    height: 100%;
}

Et voilà, vous avez intégré une fonctionnalité qui permet d’afficher des articles en relation !

Pour aller plus loin

La fonction related de Hugo est plus puissante qu’elle n’en a l’air. Quelques pistes pour exploiter son potentiel :

  • Combiner plusieurs indices : vous pouvez pondérer plusieurs taxonomies différentes (catégories à 80, tags à 60, date à 20) pour affiner la pertinence.
  • Utiliser le type fragment : pour faire matcher des champs spécifiques comme summary ou description (intéressant pour de la recherche textuelle simple).
  • Cacher la fonction : pour les gros sites, activez cardinalityThreshold pour limiter le coût de calcul.

Pour aller plus loin, la documentation officielle est à jour et bien faite : https://gohugo.io/content-management/related/

C’est une très bonne fonctionnalité pour créer des silos thématiques d’une façon plus intelligente que ce qu’on peut connaître sur d’autres systèmes !

Vous devriez également aimer ce qui suit...