Robots.txt : syntaxe, erreurs courantes et cas avancés

Un fichier robots.txt mal configuré sur un e-commerce de 28 000 pages a bloqué l'intégralité du répertoire /products/ pendant 11 jours. Résultat : 40 % du trafic organique perdu, 3 semaines pour récupérer les positions. Le fichier faisait 6 lignes. Le problème tenait à un seul caractère.

Le robots.txt est le premier fichier que Googlebot demande sur votre domaine. Il définit les limites de crawl avant même que le moteur n'ait vu une seule balise HTML. Et pourtant, c'est l'un des fichiers les plus mal compris du SEO technique.

La spécification exacte : ce que le protocole autorise (et rien d'autre)

Le robots.txt repose sur le Robots Exclusion Protocol, dont Google a publié une implémentation open-source (RFC 9309). Cette RFC, adoptée en septembre 2022, est devenue la référence normative. Toute syntaxe qui ne figure pas dans cette RFC est un comportement non standardisé — même si certains crawlers la supportent.

Les directives standardisées

Quatre éléments sont définis par la RFC :

  • User-agent : identifie le crawler ciblé
  • Allow : autorise le crawl d'un chemin
  • Disallow : interdit le crawl d'un chemin
  • Sitemap (hors RFC mais universellement supporté) : indique l'URL d'un sitemap XML

C'est tout. Crawl-delay n'est pas dans la spécification Google. Googlebot l'ignore complètement — seul Bingbot le respecte. Si vous avez besoin de réguler la fréquence de crawl Google, c'est dans la Search Console, pas dans le robots.txt.

Emplacement et encodage

Le fichier doit se trouver à la racine du domaine : https://www.example.com/robots.txt. Un fichier placé dans un sous-répertoire (/blog/robots.txt) est ignoré. Chaque sous-domaine nécessite son propre fichier. Un robots.txt sur www.monsite.fr ne s'applique pas à api.monsite.fr.

Encodage obligatoire : UTF-8. Taille maximale que Googlebot accepte de parser : 500 Ko (documentation Google Search Central). Au-delà, tout est traité comme Allow — le fichier entier est ignoré.

Syntaxe de base : un fichier minimal correct

# Bloquer l'accès aux pages d'administration
User-agent: *
Disallow: /admin/
Disallow: /tmp/

# Autoriser explicitement le crawl des ressources CSS/JS
User-agent: Googlebot
Allow: /assets/

Sitemap: https://www.monsite.fr/sitemap-index.xml

Points critiques souvent ratés :

  • Le Disallow: /admin/ bloque /admin/, /admin/settings, /admin/users/list. Le slash final délimite un répertoire.
  • Disallow: /admin (sans slash final) bloque aussi /administration, /admin-panel, et tout chemin commençant par /admin.
  • Une ligne Disallow: vide (sans valeur) signifie "tout autoriser". C'est l'inverse de Disallow: / qui bloque tout.

Wildcards et patterns : la puissance (et les pièges) du pattern matching

Google supporte deux caractères spéciaux dans les chemins : * (wildcard) et $ (fin de chaîne). Ils ne font pas partie de la RFC 9309 mais sont documentés explicitement par Google comme extensions supportées par Googlebot.

Le wildcard *

* remplace n'importe quelle séquence de caractères (y compris une séquence vide).

User-agent: Googlebot

# Bloquer tous les fichiers PDF sur le site
Disallow: /*.pdf

# Bloquer les URLs contenant un paramètre de tri
Disallow: /*?sort=

# Bloquer les pages de résultats de recherche interne
Disallow: /search/*?q=

# Bloquer les URLs de tracking avec UTM
Disallow: /*utm_

# Autoriser un répertoire spécifique malgré un Disallow global
Disallow: /catalog/internal/
Allow: /catalog/internal/public/

L'ancre de fin $

Le $ indique que l'URL doit se terminer exactement à cet endroit. C'est indispensable pour cibler des extensions sans effets de bord.

User-agent: *

# Bloquer UNIQUEMENT les URLs qui se terminent par .json
# Pas /api/json-schema ni /docs/json-guide
Disallow: /*.json$

# Bloquer les pages de pagination sans bloquer /category/page-officielle
Disallow: /*?page=*$

Sans le $, Disallow: /*.json bloquerait aussi /api/json-export/results — toute URL contenant .json suivi de n'importe quoi. C'est une source d'erreur extrêmement fréquente.

Ordre de précédence : Allow vs Disallow

Googlebot applique une règle de plus grande spécificité (longest match). La directive dont le chemin correspond le plus longtemps à l'URL testée l'emporte. En cas d'égalité de longueur, Allow gagne.

Exemple concret :

User-agent: Googlebot
Disallow: /catalog/
Allow: /catalog/produit-
  • /catalog/internal-page → bloqué (match Disallow: /catalog/, 9 caractères)
  • /catalog/produit-123 → autorisé (match Allow: /catalog/produit-, 17 caractères > 9)
  • /catalog/produit-123?ref=newsletter → autorisé (même match sur le préfixe)

Ce mécanisme est documenté sur Google Search Central. Attention : Bing et Yandex n'appliquent pas nécessairement la même logique de précédence. Si le SEO multi-moteur vous concerne, testez chaque cas.

Les erreurs qui coûtent du trafic : 6 cas réels

Erreur #1 : Bloquer les ressources CSS et JavaScript

Googlebot doit pouvoir accéder à vos fichiers CSS et JS pour le rendering. Un Disallow: /assets/ ou Disallow: /*.js empêche Google de voir votre page telle qu'un utilisateur la voit. Les conséquences :

  • Le contenu rendu côté client (React, Vue, Angular) est invisible
  • Les Core Web Vitals ne peuvent pas être évalués correctement
  • L'inspection d'URL dans la Search Console montre une page vide ou cassée

Vérification immédiate : allez dans la Search Console, outil "Inspection d'URL", et regardez la capture d'écran du rendu. Si votre page apparaît sans style ou sans contenu, vérifiez votre robots.txt.

Erreur #2 : Le Disallow qui bloque les pages paginées

Sur un site média avec 12 000 articles et une pagination /articles?page=2 à /articles?page=600, un robots.txt contenant :

Disallow: /*?page=

...bloque aussi /articles?page=2, ce qui empêche Googlebot de découvrir les articles listés sur les pages 2+. Si ces articles n'ont aucun lien interne direct depuis d'autres pages, ils deviennent des orphelins de crawl. Le sitemap XML peut compenser partiellement, mais Googlebot accorde moins de priorité aux URLs découvertes uniquement via sitemap.

La correction :

# Bloquer les paramètres de tri et de filtrage, pas la pagination
Disallow: /*?sort=
Disallow: /*?filter=
Disallow: /*?sort=*&page=
Allow: /*?page=

Erreur #3 : Confondre Disallow et noindex

Le robots.txt ne désindexe pas. Il empêche le crawl. Si une page est déjà indexée et que vous ajoutez un Disallow dessus, Google peut la garder dans l'index indéfiniment — il ne pourra simplement plus la crawler pour la mettre à jour.

Pour désindexer, vous avez besoin d'une balise meta robots noindex accessible au crawl. Paradoxe : pour que Googlebot voie le noindex, il faut qu'il puisse crawler la page — donc ne la bloquez pas dans le robots.txt.

Le seul cas où le Disallow mène à une désindexation effective : quand la page n'a plus aucun signal externe (pas de backlinks, pas de mentions). Google finit par la retirer, mais cela peut prendre des mois.

Erreur #4 : Oublier la casse

Les chemins dans le robots.txt sont sensibles à la casse. Disallow: /Admin/ ne bloque pas /admin/. Sur un serveur Linux (la majorité des hébergements), /Admin/ et /admin/ sont deux URLs distinctes. Sur IIS/Windows, elles sont identiques côté serveur mais pas côté robots.txt.

Erreur #5 : Le fichier qui renvoie un 5xx

Si votre robots.txt retourne une erreur 5xx, Google considère cela comme une restriction temporaire et arrête de crawler votre site pendant la durée de l'erreur, selon la documentation officielle. Un 4xx (fichier inexistant) est traité comme "pas de restriction" — tout est crawlable.

Moralité : un robots.txt cassé est pire qu'un robots.txt absent.

Surveillez le code HTTP de votre robots.txt. Un reverse proxy mal configuré, un CDN qui cache une erreur, ou un déploiement qui écrase le fichier par une page 404 HTML — ce sont des régressions silencieuses que seul un monitoring continu peut détecter. Un outil comme SEOGard détecte ce type de changement de statut HTTP en temps réel.

Erreur #6 : Le BOM UTF-8 invisible

Certains éditeurs de texte ajoutent un BOM (Byte Order Mark) au début des fichiers UTF-8. Ce caractère invisible (EF BB BF en hexadécimal) peut casser le parsing de la première directive User-agent. Googlebot est tolérant à ce sujet, mais d'autres crawlers ne le sont pas.

Vérification en CLI :

# Détecter un BOM dans le fichier robots.txt
hexdump -C robots.txt | head -1
# Si la sortie commence par "ef bb bf", le BOM est présent

# Supprimer le BOM avec sed
sed -i '1s/^\xEF\xBB\xBF//' robots.txt

# Vérification alternative avec curl
curl -sI https://www.monsite.fr/robots.txt | grep -i content-type
# Doit retourner: text/plain; charset=utf-8 (pas text/html)

Le Content-Type retourné par le serveur doit être text/plain. Si votre serveur renvoie text/html, certains parsers peuvent mal interpréter le contenu, surtout si le fichier contient des caractères spéciaux dans les commentaires.

Cas d'usage avancés pour sites volumineux

Gestion du crawl budget sur un e-commerce de 25 000 pages

Contexte : un e-commerce mode avec la structure suivante :

  • 8 000 pages produits
  • 3 000 pages catégories (dont 1 200 générées par les filtres de facettes)
  • 14 000 URLs de paramètres (tri, pagination, filtres combinés)

Le crawl budget est une vraie contrainte ici. Les logs serveur montrent que Googlebot passe 60 % de son budget sur les URLs de facettes — des pages à faible valeur qui diluent le crawl des fiches produits.

User-agent: Googlebot

# Bloquer les facettes multi-filtres
Disallow: /*?color=*&size=
Disallow: /*?size=*&color=
Disallow: /*?brand=*&color=
Disallow: /*?brand=*&size=

# Bloquer les tris
Disallow: /*?sort=
Disallow: /*?order=

# Bloquer la pagination au-delà de la page 10 pour les catégories
# (les produits profonds sont accessibles via sitemap)
# Note: ce n'est pas faisable avec robots.txt seul - 
# utilisez plutôt noindex + follow sur ces pages

# Autoriser les pages catégories principales
Allow: /categorie/
Allow: /produit/

Sitemap: https://www.monsite.fr/sitemap-products.xml
Sitemap: https://www.monsite.fr/sitemap-categories.xml

Limitation importante : le robots.txt ne gère pas la logique "autoriser la page 1 mais bloquer la page 15". Vous ne pouvez pas écrire de règle conditionnelle sur la valeur d'un paramètre. Pour ce cas précis, la combinaison meta robots noindex + canonical sur les pages de pagination profonde est plus adaptée.

Après optimisation du robots.txt sur ce type de site, les logs montrent typiquement un report du crawl vers les pages produits en 7-10 jours, avec une augmentation du nombre de fiches crawlées quotidiennement de l'ordre de 30-50 %.

Robots.txt et sites multi-langues

Sur un site avec des répertoires par langue (/fr/, /en/, /de/), le robots.txt est unique pour le domaine. Chaque version linguistique doit avoir ses propres règles si nécessaire :

User-agent: *

# Bloquer les pages de recherche interne dans toutes les langues
Disallow: /fr/recherche
Disallow: /en/search
Disallow: /de/suche

# Bloquer une section en cours de migration uniquement en allemand
Disallow: /de/legacy-catalog/

Sitemap: https://www.monsite.com/sitemap-fr.xml
Sitemap: https://www.monsite.com/sitemap-en.xml
Sitemap: https://www.monsite.com/sitemap-de.xml

Combiné avec les balises hreflang, le robots.txt doit être cohérent : ne bloquez pas une version linguistique si elle est référencée dans les hreflang d'une autre page — cela crée des erreurs hreflang en cascade.

Bloquer les crawlers d'IA (GPTBot, CCBot, etc.)

Depuis 2023, de nouveaux User-agents sont apparus pour le scraping de données d'entraînement IA. Si vous souhaitez bloquer ces crawlers tout en autorisant les moteurs de recherche classiques :

# Moteurs de recherche : accès normal
User-agent: Googlebot
Disallow: /admin/

User-agent: Bingbot
Disallow: /admin/
Crawl-delay: 2

# Crawlers IA : blocage total
User-agent: GPTBot
Disallow: /

User-agent: ChatGPT-User
Disallow: /

User-agent: CCBot
Disallow: /

User-agent: anthropic-ai
Disallow: /

User-agent: Google-Extended
Disallow: /

# Fallback pour les crawlers non identifiés
User-agent: *
Disallow: /admin/

Notez que Google-Extended bloque spécifiquement l'utilisation de votre contenu pour l'entraînement de Gemini, sans affecter l'indexation Google Search. Cette distinction est documentée sur Google Search Central.

Tester et valider : les outils indispensables

Google Search Console : le testeur officiel

L'outil "Test du fichier robots.txt" dans la Search Console (ancien outil, remplacé par l'API) permet de vérifier si une URL spécifique est bloquée. Mais il teste uniquement les règles pour Googlebot, pas pour les autres User-agents.

Depuis 2024, Google recommande d'utiliser la librairie open-source de parsing :

# Installation de la librairie Google de parsing robots.txt
# https://github.com/google/robotstxt
git clone https://github.com/google/robotstxt.git
cd robotstxt
mkdir build && cd build
cmake ..
make

# Tester si une URL est autorisée
./robots /chemin/vers/robots.txt "Googlebot" "https://www.monsite.fr/catalog/product-123"

Screaming Frog : validation en masse

Screaming Frog permet de lancer un crawl qui respecte (ou ignore) le robots.txt. La méthode la plus fiable pour auditer :

  1. Crawlez votre site avec le respect du robots.txt activé
  2. Crawlez à nouveau avec le robots.txt désactivé
  3. Comparez les deux exports : les URLs présentes dans le second mais absentes du premier sont bloquées

Exportez le rapport "Directives robots.txt" pour avoir la liste complète des URLs bloquées par directive.

Validation en ligne de commande

Pour les déploiements CI/CD, intégrez une vérification automatisée :

#!/bin/bash
# Script de validation robots.txt post-déploiement

ROBOTS_URL="https://www.monsite.fr/robots.txt"
CRITICAL_PATHS=(
  "/produit/"
  "/categorie/"
  "/blog/"
  "/"
)

# Vérifier le code HTTP
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$ROBOTS_URL")
if [ "$HTTP_CODE" != "200" ]; then
  echo "ERREUR CRITIQUE: robots.txt retourne HTTP $HTTP_CODE"
  exit 1
fi

# Vérifier le Content-Type
CONTENT_TYPE=$(curl -sI "$ROBOTS_URL" | grep -i "content-type" | tr -d '\r')
if [[ ! "$CONTENT_TYPE" == *"text/plain"* ]]; then
  echo "ATTENTION: Content-Type incorrect: $CONTENT_TYPE"
fi

# Vérifier la taille
SIZE=$(curl -s "$ROBOTS_URL" | wc -c)
if [ "$SIZE" -gt 512000 ]; then
  echo "ATTENTION: robots.txt dépasse 500 Ko ($SIZE bytes)"
fi

# Vérifier que les chemins critiques ne sont pas bloqués
ROBOTS_CONTENT=$(curl -s "$ROBOTS_URL")
for path in "${CRITICAL_PATHS[@]}"; do
  if echo "$ROBOTS_CONTENT" | grep -q "Disallow: $path"; then
    echo "ERREUR CRITIQUE: $path est bloqué dans robots.txt"
    exit 1
  fi
done

echo "Validation robots.txt: OK"

Ce type de script, exécuté dans une pipeline GitHub Actions ou GitLab CI, attrape les régressions avant qu'elles n'atteignent la production. C'est un filet de sécurité minimal — un monitoring continu via SEOGard couvre les cas où le fichier change après le déploiement (modification manuelle, écrasement par un CMS, cache CDN stale).

Robots.txt et JavaScript frameworks : les subtilités du rendering

Sur une Single Page Application (SPA) ou une application hybride SSR/CSR, le robots.txt interagit de manière subtile avec le processus de rendering de Google.

Le problème du pre-rendering sélectif

Si votre application Next.js ou Nuxt sert du contenu SSR pour certaines routes et du CSR pour d'autres, le robots.txt doit refléter cette architecture. Bloquer les routes CSR qui ne sont pas destinées à l'indexation réduit la charge sur le Web Rendering Service (WRS) de Google.

User-agent: Googlebot

# Bloquer les routes d'application pure CSR (espace client, dashboard)
Disallow: /app/
Disallow: /dashboard/
Disallow: /account/

# Bloquer les endpoints API que les crawlers découvrent
# via le code source JavaScript
Disallow: /api/internal/
Disallow: /_next/data/*/account
Disallow: /_next/data/*/dashboard

# Autoriser les ressources statiques nécessaires au rendering
Allow: /_next/static/
Allow: /assets/

Les chemins /_next/data/ sont des JSON endpoints utilisés par Next.js pour la navigation côté client. Si Googlebot les découvre (et il les découvre, en parsant votre JavaScript), il peut les crawler inutilement. Les bloquer libère du crawl budget pour vos pages réelles.

Interaction avec les meta tags

Le robots.txt et les meta tags SEO sont deux couches de contrôle distinctes mais complémentaires. Le robots.txt agit au niveau du crawl (avant la requête HTTP), les meta robots agissent au niveau de l'indexation (après le parsing HTML).

Un piège classique : mettre un noindex sur une page et la bloquer dans le robots.txt. Googlebot ne peut pas voir le noindex puisqu'il n'accède pas à la page. Le noindex est donc ignoré. Pour que les deux fonctionnent ensemble, la page doit être crawlable.

Configuration serveur : servir correctement le robots.txt

Nginx : configuration recommandée

# /etc/nginx/conf.d/robots.conf

# Servir le robots.txt avec les bons headers
location = /robots.txt {
    root /var/www/monsite/public;
    
    # Content-Type correct
    default_type text/plain;
    charset utf-8;
    
    # Cache court : permettre les mises à jour rapides
    expires 6h;
    add_header Cache-Control "public, max-age=21600";
    
    # Pas de transformation par le CDN
    add_header X-Robots-Tag "nosnippet";
    
    # Logging séparé pour surveiller les crawlers
    access_log /var/log/nginx/robots_access.log;
}

# Bloquer les robots.txt dans les sous-répertoires
# (ils ne sont pas valides selon la spécification)
location ~ ^/.+/robots\.txt$ {
    return 404;
}

Le expires 6h est un compromis : assez court pour que les modifications soient prises en compte rapidement, assez long pour ne pas surcharger le serveur. Google cache le robots.txt environ 24 heures, mais peut le récupérer plus fréquemment si le fichier a changé récemment.

Robots.txt dynamique (à utiliser avec précaution)

Sur certaines plateformes, le robots.txt est généré dynamiquement — par exemple pour varier les règles entre l'environnement de staging et la production :

// next.config.js — Next.js App Router
// app/robots.ts
import { MetadataRoute } from 'next'

export default function robots(): MetadataRoute.Robots {
  const isProduction = process.env.NODE_ENV === 'production'
  
  return {
    rules: [
      {
        userAgent: 'Googlebot',
        allow: isProduction ? '/' : [],
        disallow: isProduction ? ['/admin/', '/api/internal/'] : '/',
      },
      {
        userAgent: '*',
        allow: isProduction ? '/' : [],
        disallow: isProduction ? ['/admin/'] : '/',
      },
    ],
    sitemap: isProduction
      ? 'https://www.monsite.fr/sitemap-index.xml'
      : undefined,
  }
}

Le risque : si la variable d'environnement est mal configurée en production, vous servez un Disallow: / à tous les crawlers. Ce type de régression est silencieux et dévastateur. Logguez systématiquement le contenu du robots.txt servi, et comparez-le à une version de référence dans votre pipeline de déploiement.

L'essentiel à retenir

Le robots.txt est un fichier de 6 à 30 lignes qui contrôle la porte d'entrée de votre site pour les crawlers. Sa puissance vient de sa simplicité — mais cette même simplicité laisse peu de marge d'erreur. Un wildcard mal placé, un slash manquant, ou un fichier qui retourne un 5xx, et le crawl de votre site s'effondre sans alerte visible dans Google Analytics.

Traitez le robots.txt comme du code d'infrastructure : versionné dans Git, validé en CI, monitoré en production. Un outil de monitoring comme SEOGard détecte automatiquement les changements de contenu et de statut HTTP du robots.txt, ce qui transforme un incident potentiel de 11 jours en une alerte résolue en 11 minutes.

Articles connexes

Crawl7 mars 2026

Pagination SEO : rel=prev/next est mort, quelles alternatives

rel=prev/next n'est plus interprété par Google. Découvrez les stratégies modernes de pagination SEO pour sites volumineux : architecture, crawl et indexation.

Crawl7 mars 2026

URL Inspection API : automatiser le diagnostic d'indexation

Exploitez l'API URL Inspection de Search Console pour surveiller l'indexation à grande échelle. Code, architecture et cas concrets.

Crawl6 mars 2026

Index bloat : identifier et éliminer l'inflation d'index

Diagnostic et résolution de l'index bloat : méthodes concrètes pour réduire les pages inutiles indexées et récupérer du crawl budget.