---
title: "SEO Hugo : 404 Googlebot, aliases noindex et normalisation des sitemaps"
description: "Diagnostic et correction des 404 Googlebot, des 16 pages noindex générées par Hugo aliases, de la balise robots noodp, des tags FR non accentués et du bug de boucle sur /fr/sitemap.xml."
url: "https://www.arleo.eu/posts/debug-seo-404-broken-links/"
language: "fr"
datePublished: "2026-05-29T20:30:00+02:00"
dateModified: "2026-05-29T20:30:00+02:00"
tags: ["hugo","seo","nginx","cloudflare","Infrastructure","homelab"]
categories: ["Infrastructure","Post-mortems"]
contentSignal: "ai-train=no, search=yes, ai-input=yes"
---

# SEO Hugo : 404 Googlebot, aliases noindex et normalisation des sitemaps
Diagnostic et correction des 404 Googlebot, des 16 pages noindex générées par Hugo aliases, de la balise robots noodp, des tags FR non accentués et du bug de boucle sur /fr/sitemap.xml.



## 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** : `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 :

```html
<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 :

```nginx
# === 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` :

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

```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

```bash
# 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

```bash
# 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 :

```bash
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 :

```bash
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 :

```nginx
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

<!-- mermaid-source:Zmxvd2NoYXJ0IExSCiAgICBBWyJHU0Mgc2lnbmFsZVxuNDA0ICsgbm9pbmRleCJdIC0tPiBCWyJhbGlhc2VzIEh1Z29cbkhUTUwgbm9pbmRleCJdCiAgICBCIC0tPiBDWyI1OSByZXdyaXRlIG5naW54XG4zMDEgcGVybWFuZW50Il0KICAgIEEgLS0+IERbIm5vb2RwIGRhbnNcbmJhc2VvZi5odG1sIl0KICAgIEQgLS0+IEVbImluZGV4IGZvbGxvd1xuc2l0ZSBvdmVycmlkZSJdCiAgICBBIC0tPiBGWyJUYWdzIEZSXG5zYW5zIGFjY2VudHMiXQogICAgRiAtLT4gR1sic2VkIGJhdGNoXG43IHBvc3RzIl0KICAgIEcgLS0+IEhbInNpdGVtYXBcbkZSPUVOPTEwNSJdCiAgICBBIC0tPiBJWyIvZnIvc2l0ZW1hcC54bWxcbmJvdWNsZSAzMDEiXQogICAgSSAtLT4gSlsiYnJlYWsgZXhjZXB0aW9uXG5yZXdyaXRlIG5naW54Il0KICAgIEMgLS0+IEtbInJlYnVpbGQgKyBwdXJnZSBDRiJdCiAgICBFIC0tPiBLCiAgICBIIC0tPiBLCiAgICBKIC0tPiBLCiAgICBLIC0tPiBMWyJHU0M6IDAgbm9pbmRleFxuMCA0MDQgdGFnc1xuc2l0ZW1hcHMgcGFyaXTDqSJd -->
{{< mermaid-svg hash="5860cbdb" >}}

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


## Tags

- hugo
- seo
- nginx
- cloudflare
- Infrastructure
- homelab

## Categories

- Infrastructure
- Post-mortems
