« Aucun résultat pour votre recherche » : ce message s’affichait bien trop souvent sur un site éditorial à plusieurs milliers d’articles, y compris sur des requêtes parfaitement légitimes comportant une simple faute de frappe. Le moteur de recherche natif de WordPress, basé sur une correspondance de mots-clés stricte dans le titre et le contenu, ne tolère aucune approximation et ne classe pas les résultats par pertinence réelle.
Pourquoi ne pas se contenter d’un plugin de recherche
Plusieurs extensions de recherche existent dans l’écosystème WordPress, mais la plupart reposent encore sur une indexation MySQL classique, avec les mêmes limites de tolérance aux fautes. Algolia, service de recherche hébergé spécialisé dans la recherche instantanée et tolérante aux fautes, a été choisi pour ce projet, avec une intégration directement dans le template search.php du thème plutôt que via un plugin généraliste, pour garder un contrôle total sur l’affichage des résultats.
Indexer le contenu vers Algolia
Un hook sur la sauvegarde d’article pousse chaque contenu publié vers l’index Algolia, via le SDK PHP officiel installé par Composer dans le thème :
require_once get_stylesheet_directory() . '/vendor/autoload.php';
use Algolia\AlgoliaSearch\SearchClient;
add_action( 'save_post', function( $post_id ) {
if ( 'publish' !== get_post_status( $post_id ) || wp_is_post_revision( $post_id ) ) {
return;
}
$client = SearchClient::create( getenv( 'ALGOLIA_APP_ID' ), getenv( 'ALGOLIA_ADMIN_KEY' ) );
$index = $client->initIndex( 'articles_site' );
$index->saveObject( array(
'objectID' => $post_id,
'titre' => get_the_title( $post_id ),
'extrait' => wp_strip_all_tags( get_the_excerpt( $post_id ) ),
'url' => get_permalink( $post_id ),
) );
} );

Le template search.php sans rechargement de page
Le fichier search.php du thème conserve son rôle de gabarit WordPress classique, mais délègue l’affichage réel des résultats à la bibliothèque InstantSearch.js, chargée via wp_enqueue_script et connectée à l’index Algolia côté client, avec une clé de recherche publique en lecture seule (jamais la clé d’administration) :
<?php get_header(); ?>
<div id="algolia-searchbox"></div>
<div id="algolia-resultats"></div>
<?php get_footer(); ?>
const recherche = instantsearch( {
indexName: 'articles_site',
searchClient: algoliasearch( 'APP_ID', 'CLE_RECHERCHE_PUBLIQUE' ),
} );
recherche.addWidgets( [
instantsearch.widgets.searchBox( { container: '#algolia-searchbox' } ),
instantsearch.widgets.hits( {
container: '#algolia-resultats',
templates: {
item: '<a href="{{url}}">{{titre}}</a><p>{{extrait}}</p>',
},
} ),
] );
recherche.start();
Les résultats s’affichent au fil de la frappe, sans rechargement de la page, avec la tolérance aux fautes native d’Algolia qui remonte des résultats pertinents même sur une orthographe approximative.
Retirer les contenus supprimés ou dépubliés
La synchronisation ne s’arrête pas à la publication : un hook sur le passage en corbeille ou la dépublication retire l’objet correspondant de l’index, pour éviter que la recherche ne pointe vers des contenus qui n’existent plus :
add_action( 'transition_post_status', function( $nouveau, $ancien, $post ) {
if ( 'publish' === $ancien && 'publish' !== $nouveau ) {
$client = SearchClient::create( getenv( 'ALGOLIA_APP_ID' ), getenv( 'ALGOLIA_ADMIN_KEY' ) );
$client->initIndex( 'articles_site' )->deleteObject( $post->ID );
}
}, 10, 3 );
Ce que cette intégration laisse de côté
Ce tutoriel couvre uniquement la recherche d’articles éditoriaux. L’indexation des produits WooCommerce suivrait une logique distincte, avec ses propres attributs (prix, stock, variations), non traitée ici. La facturation Algolia, dépendante du volume de requêtes et de la taille de l’index, doit également être suivie séparément selon la volumétrie réelle du site.
En résumé
Remplacer la recherche native de search.php par une intégration Algolia directe redonne une tolérance aux fautes et une pertinence de résultats que le moteur MySQL natif de WordPress ne propose pas, sans passer par un plugin généraliste qui aurait imposé sa propre structure d’affichage.