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.

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.