Contenu

SEO Hugo : 404 Googlebot et aliases noindex

Ce qui s'est passé
  • Date : 29 mai 2026
  • Sévérité : P3
  • Statut : Résolu
  • Impact : 4 catégories de problèmes SEO remontées par Google Search Console (404 Googlebot, 16 pages noindex, balise robots obsolète, désynchronisation sitemap FR/EN 104 vs 105)

En bref

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 : noodp hardcodé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 noodpindex, 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 correspondant ré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
done

Ajout 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/securite

Ré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.xml

Fix : 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

Diagram Diagram
ProblèmeCauseFix
404 /fr/tag/*Singulier + préfixe non gérérewrite ^/fr/tag/ + ^/tag/
16 pages noindex GSCaliases: Hugo génère HTML noindexnginx 301 + suppression aliases
robots: noodpLoveIt baseof.html hardcodéOverride layouts/baseof.html
Sitemap FR 104 vs EN 105Tags doublon + tags manquantssed batch + ajout tags
/fr/sitemap.xml boucle^/fr/(.+) trop génériquebreak exception avant la règle