SEO Hugo : 404 Googlebot, aliases noindex et normalisation des sitemaps

Contexte
Google Search Console remontait quatre catégories de problèmes sur arleo.eu :
- 404 Googlebot :
/fr/tag/cloudflare,/en/tag/nginx,/fr/tag/javascript… URLs avec préfixe/fr/ou singulier/tag/jamais servi par nginx - 16 pages “Exclue par la balise noindex” : toutes des pages de redirection générées par
aliases:dans le frontmatter Hugo - Balise robots :
noodphardcodée dans le thème LoveIt - Sitemap FR/EN : 104 vs 105 URLs — un tag doublon FR et deux tags manquants
Acte 1 : aliases Hugo → redirections nginx 301
Pourquoi Hugo génère des pages noindex
Hugo génère les entrées aliases: du frontmatter comme des fichiers HTML statiques :
<meta http-equiv="refresh" content="0; url=https://www.arleo.eu/posts/X/">
<meta name="robots" content="noindex">Le noindex est intentionnel côté Hugo : il empêche Google d’indexer la page de redirection au lieu de la destination. Mais GSC le remonte comme “Exclue par la balise noindex” — ce qui pollue le rapport et signale à Google que des URLs de votre site lui sont intentionnellement cachées.
Fix : nginx permanent + suppression des aliases
59 règles rewrite ... permanent dans le vhost NUC :
# === Redirections SEO ===
# 1. Anciens slugs Grav et alias Hugo
rewrite ^/crowdsec-cloudflare-waf-autoban/?$ /posts/crowdsec-cloudflare-waf-autoban/ permanent;
rewrite ^/en/crowdsec-cloudflare-waf-autoban/?$ /en/posts/crowdsec-cloudflare-waf-autoban/ permanent;
rewrite ^/fr/crowdsec-cloudflare-waf-autoban/?$ /posts/crowdsec-cloudflare-waf-autoban/ permanent;
# ... (56 autres règles spécifiques)
# 2. Préfixe /fr/ — langue par défaut, pas de sous-répertoire
rewrite ^/fr/tag/([^/]+)/?$ /tags/$1/ permanent;
rewrite ^/fr/(.+)$ /$1 permanent;
# 3. Singulier /tag/ → pluriel /tags/ (taxonomie Hugo)
rewrite ^/tag/([^/]+)/?$ /tags/$1/ permanent;
rewrite ^/en/tag/([^/]+)/?$ /en/tags/$1/ permanent;
# 4. Tags FR dans le contexte EN
rewrite ^/en/tags/reseau/?$ /en/tags/network/ permanent;
rewrite ^/en/tags/securite/?$ /en/tags/security/ permanent;Suppression des blocs aliases: dans les 35 fichiers Markdown concernés. Hugo reconstruit avec 68 alias (seuls les aliases inter-langues automatiques subsistent) au lieu de 208.
Résultat : les redirections sont des 301 purs nginx, invisibles pour GSC comme pages noindex.
Acte 2 : balise robots noodp → index, follow
Le thème LoveIt injecte dans baseof.html :
<meta name="robots" content="noodp" />noodp était destiné à interdire l’utilisation du titre Open Directory Project (DMOZ) dans les snippets Google. DMOZ a fermé en 2017, la directive est sans effet depuis des années — mais certains crawlers l’interprètent encore comme une contrainte d’indexation.
Override au niveau site dans layouts/baseof.html :
<meta name="robots" content="index, follow" />Ce fichier prend priorité sur le template du thème sans modifier le thème lui-même.
Acte 3 : normalisation des tags FR et parité des sitemaps
Diagnostic
# Extraire et comparer les chemins FR vs EN
sed 's|https://www.arleo.eu||' sitemap_fr.txt | sort > fr_paths.txt
sed 's|https://www.arleo.eu/en||' sitemap_en.txt | sort > en_paths.txt
comm -13 fr_paths.txt en_paths.txt # Dans EN, absent de FR
# → /tags/network/ /tags/security/ /tags/performance/ /tags/purge/ /categories/security/
comm -23 fr_paths.txt en_paths.txt # Dans FR, absent de EN
# → /tags/reseau/ /tags/securite/ /tags/sécurité/ /categories/sécurité/FR avait :
/tags/securite/ET/tags/sécurité/— doublon non accentué vs accentué/tags/reseau/— non accentué, sans correspondantréseau
EN avait en plus : /tags/performance/ et /tags/purge/ sans équivalent FR.
Corrections
# 5 posts FR : securite → sécurité
for post in audit-securite-modsecurity-crowdsec csp-nonce hardening-systemd-mcp \
roadmap-sprint-securite-mcp sprint-securite-mcp-livre; do
sed -i 's/^- securite$/- sécurité/' content/posts/$post/index.fr.md
done
# 2 posts FR : reseau → réseau
for post in crowdsec-cloudflare-waf-autoban post-mortem-522-wan-failover; do
sed -i 's/^- reseau$/- réseau/' content/posts/$post/index.fr.md
doneAjout de purge et performance dans hugo-mcp-plugin-cloudflare/index.fr.md.
Nettoyage des répertoires obsolètes dans public/ — Hugo ne supprime pas les anciens fichiers lors d’un rebuild incrémental :
rm -rf public/tags/reseau public/tags/securiteRésultat : FR 105 = EN 105.
Acte 4 : boucle de redirection /fr/sitemap.xml
La règle générale rewrite ^/fr/(.+)$ /$1 permanent interceptait /fr/sitemap.xml — un fichier réel généré par Hugo — et le redirigeait vers /sitemap.xml (l’index de sitemaps). L’index liste… /fr/sitemap.xml. Boucle infinie pour les crawlers.
Détection :
curl -sk https://www.arleo.eu/fr/sitemap.xml -o /dev/null -w '%{http_code} → %{redirect_url}\n'
# 301 → https://www.arleo.eu/sitemap.xmlFix : exception break avant la règle générale :
rewrite ^/fr/(sitemap\.xml)$ /fr/$1 break;
rewrite ^/fr/tag/([^/]+)/?$ /tags/$1/ permanent;
rewrite ^/fr/(.+)$ /$1 permanent;break stoppe le traitement des rewrites. La requête passe ensuite au bloc location ~* sitemap\.xml$ qui proxifie vers la VM Hugo.
Piège nginx : les rewrites dans le contexte server s’exécutent avant les blocs location. Un break sans changement d’URI laisse donc la requête continuer vers le bon location.
Bilan
| Problème | Cause | Fix |
|---|---|---|
404 /fr/tag/* |
Singulier + préfixe non géré | rewrite ^/fr/tag/ + ^/tag/ |
| 16 pages noindex GSC | aliases: Hugo génère HTML noindex |
nginx 301 + suppression aliases |
robots: noodp |
LoveIt baseof.html hardcodé | Override layouts/baseof.html |
| Sitemap FR 104 vs EN 105 | Tags doublon + tags manquants | sed batch + ajout tags |
/fr/sitemap.xml boucle |
^/fr/(.+) trop générique |
break exception avant la règle |