# Générer un robots.txt dynamique par filtre WordPress, sans fichier statique

> Un client avec trois environnements et un seul robots.txt : la solution passe par un filtre WordPress, pas par un fichier posé à la racine.

- Auteur : Clément Hadrot
- Publié le : 2020-01-14
- Mis à jour le : 2020-01-14
- Catégorie : SEO &amp; GEO
- URL : https://wpmoderne.dev.wordpress-developpement.fr/seo/generer-robots-txt-dynamique-filtre-wordpress/

## L’essentiel

- Un seul filtre remplace trois fichiers statiques différents
- Le contenu s'adapte à l'environnement sans intervention manuelle
- Compatible avec un déploiement Git sans fichier à exclure

Un client vient d'ajouter un environnement de recette entre le développement local et la production, et le robots.txt posé manuellement à la racine du serveur de recette autorise les moteurs à tout indexer. Résultat : deux semaines plus tard, une poignée d'URL de recette apparaissent dans les résultats de recherche, avec un contenu à moitié terminé. La cause est bête : un fichier statique copié depuis la production, jamais adapté.

WordPress évite justement ce genre de piège depuis longtemps, à condition de connaître le bon mécanisme. Plutôt que de déposer un fichier `robots.txt` physique à la racine, il est possible de laisser WordPress générer ce fichier à la volée, avec un contenu qui dépend de l'environnement courant. Voici comment procéder proprement, sans plugin dédié.

## Comment WordPress sert déjà un robots.txt virtuel

Dès lors qu'aucun fichier `robots.txt` physique n'existe à la racine du site, WordPress prend le relais. La fonction `do_robots()`, définie dans `wp-includes/functions.php`, est appelée via l'action `do_robotstxt` lorsqu'une requête cible `/robots.txt`. Elle construit un contenu par défaut qui varie selon un réglage précis : l'option « Visibilité par les moteurs de recherche » du site, présente dans Réglages → Lecture.

Si cette option est décochée (le cas classique d'un site de recette), WordPress renvoie un robots.txt qui bloque tout : `Disallow: /`. Dans le cas contraire, il autorise l'exploration mais bloque certains chemins internes comme `/wp-admin/`. C'est ce comportement par défaut qu'il faut enrichir plutôt que remplacer entièrement.

## Le filtre robots_txt pour reprendre la main

Le filtre à utiliser s'appelle `robots_txt`. Il reçoit deux arguments : le contenu généré par défaut, et un booléen indiquant si le site est public. On peut l'utiliser pour ajouter des règles, ou reconstruire totalement la sortie selon l'environnement détecté.

```
add_filter( 'robots_txt', function ( $output, $public ) {
    $env = wp_get_environment_type(); // 'local', 'development', 'staging', 'production'

    if ( 'production' !== $env ) {
        return "User-agent: *\nDisallow: /\n";
    }

    $output  = "User-agent: *\n";
    $output .= "Disallow: /wp-admin/\n";
    $output .= "Allow: /wp-admin/admin-ajax.php\n";
    $output .= "Disallow: /?s=\n";
    $output .= "Sitemap: " . home_url( '/wp-sitemap.xml' ) . "\n";

    return $output;
}, 10, 2 );
```

La fonction `wp_get_environment_type()` lit la constante `WP_ENVIRONMENT_TYPE`, définie dans `wp-config.php` ou en variable d'environnement serveur. C'est exactement ce qu'il faut pour distinguer développement, recette et production sans dupliquer de fichier : une seule base de code, un comportement qui change selon la constante active.

> L'essentiel à retenir : Un seul filtre remplace trois fichiers statiques différents ; Le contenu s'adapte à l'environnement sans intervention manuelle ; Compatible avec un déploiement Git sans fichier à exclure

## Adapter le contenu à des règles plus fines

Le filtre accepte n'importe quelle logique PHP. On peut par exemple bloquer les pages de résultats de recherche interne, les flux de commentaires, ou les archives d'auteur d'un site à auteur unique, tout en gardant les règles génériques pour le reste :

- Bloquer `/?s=` et `/page/*/?s=` pour éviter d'exposer la recherche interne aux moteurs
- Ajouter `Disallow: /*?replytocom=` si le thème n'utilise pas de commentaires imbriqués proprement gérés
- Déclarer explicitement l'URL du sitemap natif, utile quand celui-ci a été déplacé ou renommé via un autre filtre

## Pourquoi éviter le fichier statique en même temps

Un fichier robots.txt physique prime toujours sur le mécanisme virtuel de WordPress : si un fichier existe à la racine, `do_robots()` n'est jamais appelée. C'est une source d'erreurs fréquente après une migration, quand un ancien fichier traîne encore sur le serveur suite à un export FTP. Avant de mettre en place le filtre, il faut donc vérifier qu'aucun fichier ne subsiste physiquement, avec un simple test :

```
ls -la /var/www/monsite/robots.txt 2>/dev/null && echo "Fichier statique présent, à supprimer"
```

> Sur les projets suivis en intégration continue, ajoutez cette vérification comme étape de déploiement plutôt que de la refaire à la main à chaque mise en production : un fichier oublié annule silencieusement tout le travail du filtre.

## Limites à connaître avant de généraliser la méthode

Cette approche a un inconvénient : elle dépend entièrement de PHP et de WordPress pour répondre, ce qui ajoute une requête au cycle de démarrage complet (chargement de `wp-load.php`) à chaque appel de `/robots.txt`. Sur un site à fort trafic de robots, mieux vaut mettre ce contenu en cache via une règle serveur ou un plugin de cache de page qui reconnaît cette route. Autre point : certains hébergeurs mutualisés imposent déjà un fichier robots.txt statique non modifiable à la racine, auquel cas le filtre reste inopérant et il faut négocier avec l'hébergeur ou changer d'offre.

## Ce qu'il faut retenir

Le filtre `robots_txt` combiné à `wp_get_environment_type()` remplace avantageusement trois fichiers statiques maintenus à la main sur trois environnements différents. La bascule est rapide, le risque d'oubli disparaît, et le comportement reste versionné dans le dépôt Git du thème ou d'un plugin maison, ce qui est nettement plus sain qu'un fichier orphelin sur un serveur de recette.
