Comment afficher une trentaine de formules de séjour, permettre de les filtrer par durée et par budget, et éviter qu’un clic sur un filtre recharge toute la page ? C’est la question posée par un office de tourisme qui voulait moderniser sa page « Nos séjours » sans budget pour une extension de recherche dédiée ni pour un développement JavaScript sur mesure.
La réponse tient dans la combinaison de deux briques natives : une Query Loop qui affiche les formules comme type de contenu personnalisé, et l’Interactivity API qui gère le filtrage côté client sans recharger la page ni faire une nouvelle requête au serveur à chaque clic.
Le contexte : des formules variées, un seul gabarit d’archive
Les formules de séjour sont enregistrées comme type de contenu personnalisé « sejour », avec des champs personnalisés pour la durée en nombre de nuits, le budget indicatif et la saison recommandée. Le gabarit d’archive utilise une Query Loop classique pour les afficher toutes, triées par ordre de saison.
Le besoin exprimé par l’office de tourisme était simple à formuler mais coûteux à développer avec les méthodes classiques : ajouter des boutons de filtre au-dessus de la liste, et ne montrer que les formules correspondant aux critères sélectionnés, instantanément.
La mécanique avec l’Interactivity API
L’Interactivity API, stable depuis WordPress 6.5, permet d’attacher un état réactif à des éléments du DOM sans réécrire la Query Loop en JavaScript. Chaque carte de séjour reçoit des attributs de données représentant ses critères, et un petit magasin d’état gère le filtrage visuel.
<div
data-wp-interactive="office-tourisme/filtres"
data-wp-context='{ "duree": "toutes", "budget": "tous" }'
>
<button data-wp-on--click="actions.filtrerDuree" data-wp-context='{ "valeur": "court" }'>
Court séjour
</button>
<!-- La Query Loop des formules suit ici -->
</div>
Côté JavaScript, un fichier de vue déclare les actions et les callbacks, en s’appuyant sur store() pour définir la logique de filtrage sans dépendre d’une bibliothèque externe :

import { store, getContext } from '@wordpress/interactivity';
store( 'office-tourisme/filtres', {
actions: {
filtrerDuree() {
const { valeur } = getContext();
const contexteGlobal = getContext( 'office-tourisme/filtres' );
contexteGlobal.duree = valeur;
},
},
callbacks: {
estVisible() {
const { duree } = getContext();
const contexteGlobal = getContext( 'office-tourisme/filtres' );
return contexteGlobal.duree === 'toutes' || contexteGlobal.duree === duree;
},
},
} );
Ce que ça change pour l’office de tourisme
Chaque carte de séjour issue de la Query Loop reçoit un attribut data-wp-bind--hidden lié au callback estVisible, ce qui masque ou affiche la carte sans requête supplémentaire vers le serveur. Le visiteur clique sur « court séjour », les cartes se filtrent immédiatement, sans latence perceptible ni rechargement de l’URL.
- Le référencement n’est pas pénalisé : toutes les formules restent présentes dans le HTML rendu côté serveur.
- Aucune extension de recherche ou de filtrage tierce n’a été installée pour ce besoin précis.
- La logique de filtrage reste portable d’une page à l’autre, en changeant simplement les critères exposés en contexte.
Les limites à connaître avant de se lancer
Cette approche convient à un volume raisonnable de formules affichées en une seule page, disons une trentaine tout au plus. Au-delà, charger toutes les cartes puis les masquer côté client devient moins pertinent qu’une pagination côté serveur, et il faudrait alors reconsidérer l’architecture en faveur d’une requête filtrée directement dans la Query Loop.
L’Interactivity API ne remplace pas une recherche côté serveur pour de gros volumes ; elle excelle en revanche pour du filtrage instantané sur une liste de taille raisonnable.
Notre verdict
Pour un office de tourisme avec une trentaine de formules à présenter, brancher l’Interactivity API sur une Query Loop existante offre un filtrage fluide sans extension supplémentaire ni développement JavaScript lourd. La réservation elle-même reste hors périmètre de cette approche : elle nécessite un système dédié, distinct du simple affichage filtré des formules.