# Brancher une Query Loop sur l’Interactivity API stable : gain surtout mobile

> Comment brancher l'Interactivity API stable de WordPress 6.5 sur une Query Loop pour obtenir une pagination fluide, sans rechargement de page ni bibliothèque JavaScript externe.

- Auteur : Clément Hadrot
- Publié le : 2024-12-26
- Mis à jour le : 2024-12-26
- Catégorie : FSE
- URL : https://wpmoderne.dev.wordpress-developpement.fr/fse/interactivity-api-pagination-query-loop/

## L’essentiel

- L'Interactivity API est stable depuis WordPress 6.5
- La pagination se fait par appel REST en arrière-plan
- Le gain perçu se mesure surtout sur mobile

Comment afficher une deuxième page de résultats d'une Query Loop sans recharger la page entière ? C'est la question posée par un client éditeur qui voulait un annuaire d'articles paginé, avec une transition fluide digne d'une application, mais sans ajouter React ni aucune bibliothèque front supplémentaire au thème.

La réponse tient dans l'Interactivity API, devenue stable avec WordPress 6.5. Elle fournit un jeu de directives HTML (`data-wp-interactive`, `data-wp-on`, `data-wp-context`) et une petite bibliothèque cliente qui remplace avantageusement du jQuery artisanal, tout en restant légère et pensée pour les blocs.

## Étape 1 : préparer le bloc de pagination

La pagination native de la Query Loop repose sur le bloc `core/query-pagination`, qui génère des liens classiques (`<a href>`) vers des URL avec un paramètre de page. Pour la rendre interactive sans casser le fonctionnement de base (accessibilité, indexation), on ne remplace pas le bloc : on l'enrichit via un bloc enfant personnalisé enregistré avec son propre `block.json`, doté de `"supports": { "interactivity": true }`.

```
{
  "name": "monclient/pagination-douce",
  "supports": { "interactivity": true },
  "viewScriptModule": "file:./view.js"
}
```

## Étape 2 : déclarer le store côté serveur et côté client

Le rendu PHP du bloc initialise l'état partagé avec `wp_interactivity_state()`, en y plaçant la page courante et l'identifiant de la Query Loop ciblée :

> L'essentiel à retenir : L'Interactivity API est stable depuis WordPress 6.5 ; La pagination se fait par appel REST en arrière-plan ; Le gain perçu se mesure surtout sur mobile

```
wp_interactivity_state( 'monclient/pagination-douce', array(
    'pageCourante' => 1,
    'chargement'   => false,
) );
```

Le fragment de template associe ensuite le contexte au conteneur de la Query Loop via `wp_interactivity_data_wp_context()`, ce qui permet à chaque instance du bloc sur la page de garder son propre état, indépendamment des autres.

## Étape 3 : écrire les actions côté client

Le fichier `view.js` importe `store` depuis `@wordpress/interactivity` et déclare une action déclenchée au clic sur le lien « page suivante » :

```
import { store, getContext } from '@wordpress/interactivity';

store( 'monclient/pagination-douce', {
  actions: {
    *pageSuivante() {
      const context = getContext();
      context.chargement = true;
      const reponse = yield fetch(
        `/wp-json/wp/v2/posts?page=${ context.pageCourante + 1 }`
      );
      const articles = yield reponse.json();
      context.pageCourante += 1;
      context.chargement = false;
      // Mise à jour du DOM via la directive data-wp-each côté template.
    },
  },
} );
```

La directive `data-wp-on--click="actions.pageSuivante"` posée sur le lien de pagination remplace le comportement de navigation classique par cet appel asynchrone, sans empêcher le lien de fonctionner en JavaScript désactivé grâce à l'attribut `href` conservé en repli.

## Étape 4 : afficher un état de chargement pendant la requête

Le contexte partagé `chargement` permet d'afficher un indicateur visuel discret pendant l'appel REST, via une simple directive `data-wp-class--is-chargement="context.chargement"` posée sur le conteneur de la liste d'articles. Aucune classe JavaScript à gérer manuellement : l'Interactivity API se charge de synchroniser la classe CSS avec l'état.

## Ce que l'on a mesuré

Sur les projets où cette approche a été mise en place, le gain le plus net se ressent sur mobile : la suppression du rechargement complet de page évite le clignotement du fond d'écran et le décalage de mise en page (repaint du header, des polices web). Sur desktop, la différence perçue est plus discrète, la navigation étant déjà rapide grâce au cache serveur.

- Le temps entre le clic et l'affichage des nouveaux articles reste sous la seconde sur une connexion correcte.
- Le poids ajouté au bundle JavaScript est minime, l'Interactivity API étant déjà chargée par le cœur dès qu'un bloc l'utilise.
- Le comportement de repli (navigation classique) fonctionne sans configuration supplémentaire.

> Sur ce projet, on a délibérément laissé le lien de pagination classique fonctionnel en arrière-plan : la directive interactive vient en surcouche, jamais en remplacement du HTML natif.

## Pour aller plus loin

Cette implémentation ne couvre volontairement pas la mise à jour de l'URL (gestion de l'historique de navigateur) ni les aspects d'accessibilité complets d'une pagination dynamique (annonce ARIA live des nouveaux résultats, gestion du focus). Ces points méritent un traitement à part entière, que ce soit via l'API History native ou des régions `aria-live` dédiées. La documentation officielle sur l'[Interactivity API](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/) reste la référence à suivre pour approfondir les directives disponibles.
