Un catalogue de recettes de cuisine avec filtrage par ingrédient et pagination classique rechargeait entièrement la page à chaque clic sur « page suivante » ou changement de filtre — fonctionnel, mais avec un flash blanc visible et une perte de la position de défilement à chaque interaction, ce qui frustrait les utilisateurs sur mobile en particulier.
Le package @wordpress/interactivity-router, qui s’appuie sur les fondations de l’Interactivity API stabilisée en WordPress 6.5, permet d’intercepter ces navigations et de ne remplacer que la portion de page réellement concernée, sans rechargement complet ni framework JavaScript supplémentaire côté front.
Ce que fait réellement le router
Le router de l’Interactivity API intercepte les clics sur les liens internes situés à l’intérieur d’une région marquée, récupère la page de destination en arrière-plan via fetch, puis ne remplace que le contenu des régions correspondantes dans le DOM actuel, en préservant l’état des composants qui n’ont pas besoin de changer. Ce n’est pas un routeur d’application au sens React Router : il ne prend en charge que la navigation entre pages WordPress classiques, en optimisant la transition visuelle.
Délimiter une région de navigation
La directive data-wp-router-region marque la portion de page que le router doit surveiller et remplacer lors d’une navigation interceptée. Tout ce qui se trouve hors de cette région suit le comportement de navigation par défaut du navigateur.
<div
data-wp-interactive="agence/catalogue-recettes"
data-wp-router-region="liste-recettes"
>
<ul>
<!-- wp:template-part... résultats de la recherche -->
</ul>
<nav>
<a data-wp-on--click="actions.allerPagePrecedente" href="?page=2">Page précédente</a>
<a data-wp-on--click="actions.allerPageSuivante" href="?page=4">Page suivante</a>
</nav>
</div>
Côté module de vue, l’action déclenchée appelle l’API navigate() exposée par le router plutôt que de laisser le navigateur suivre le lien nativement :
import { store, getContext } from '@wordpress/interactivity';
store( 'agence/catalogue-recettes', {
actions: {
*allerPageSuivante( evenement ) {
evenement.preventDefault();
const { actions } = yield import( '@wordpress/interactivity-router' );
yield actions.navigate( evenement.target.href );
},
},
} );

Gérer l’état de chargement
Le router expose un état global navigation.hasStarted et navigation.hasFinished consultable via le store, ce qui permet d’afficher un indicateur visuel pendant que la nouvelle page se charge en arrière-plan — utile en particulier sur une connexion mobile plus lente où la transition n’est pas instantanée.
<div data-wp-class--chargement="state.navigation.hasStarted">
<!-- contenu de la liste -->
</div>
Ce que le router ne remplace pas
Un point de confusion fréquent : le router de l’Interactivity API ne transforme pas le site en application monopage. Chaque navigation interceptée récupère toujours une vraie page HTML côté serveur (générée normalement par WordPress, avec son propre rendu de template), le router se contentant d’en extraire les régions marquées pour les injecter dans la page courante. Cela signifie que le référencement naturel n’est pas affecté : chaque URL reste une page complète et indexable indépendamment.
Cette approche a aussi une limite concrète : si la structure des régions diffère significativement entre la page de départ et la page de destination (un gabarit différent, par exemple), le router peut ne pas retrouver de correspondance et déclencher un rechargement complet classique en repli — un comportement voulu plutôt qu’un bug, pour ne jamais afficher un état incohérent.
Précharger au survol
Une option complémentaire, activable par lien, précharge la page cible dès que l’utilisateur survole ou approche le lien, pour réduire encore la latence perçue au clic :
<a data-wp-on--mouseenter="actions.precharger" href="?page=4">Page suivante</a>
Limites rencontrées sur ce projet
- Les scripts tiers qui s’attendent à un événement
DOMContentLoadedclassique à chaque changement de page (un widget de chat externe, par exemple) ne se redéclenchent pas automatiquement lors d’une navigation interceptée par le router — il a fallu les ré-initialiser manuellement via un abonnement à l’événement de fin de navigation du router. - Le bouton retour du navigateur fonctionne nativement grâce à l’intégration avec l’API History, mais nécessite de tester spécifiquement ce scénario, car un état local mal synchronisé peut afficher une liste de résultats qui ne correspond plus à l’URL affichée.
Le conseil qu’on retient : n’activer le router que sur les régions qui en tirent un bénéfice réel et mesurable. L’activer sur l’intégralité d’un site sans discernement ajoute de la complexité de débogage pour un gain souvent marginal sur des pages qui ne changent pas fréquemment de contenu.
En résumé
Le router de l’Interactivity API offre une navigation fluide sans les compromis habituels d’une application monopage — le référencement naturel reste intact car chaque page reste une vraie page WordPress. Sur ce catalogue de recettes, le passage au router a supprimé le flash blanc de rechargement et préservé la position de défilement entre deux pages de résultats, pour un coût de développement limité aux régions réellement concernées par le filtrage.