# Deux Query Loop imbriqués : ce qui casse quand les requêtes se chevauchent

> Symptôme, diagnostic et correctif quand deux blocs Query imbriqués affichent le même contenu en boucle au lieu de deux listes distinctes.

- Auteur : Clément Hadrot
- Publié le : 2025-03-05
- Mis à jour le : 2025-03-05
- Catégorie : Blocs Gutenberg
- URL : https://wpmoderne.dev.wordpress-developpement.fr/blocs/deux-query-loop-imbriques-conflits-requetes/

## L’essentiel

- Le contexte queryId manquant fait hériter le mauvais article
- Un queryId distinct par bloc Query résout la confusion
- Le mode aperçu masque parfois le bug jusqu'à la publication

Deux blocs Query Loop imbriqués affichent la même liste d'articles, ou pire, le contenu de la boucle extérieure fuite dans la boucle intérieure : ce symptôme revient régulièrement chez les intégrateurs qui composent des mises en page avec plusieurs boucles de requête sur une même page. Ce billet ne traite pas des popovers de réglage du bloc Query, déjà documentés ailleurs, mais uniquement de ce chevauchement de contexte.

Le scénario type : un bloc Query externe affiche une liste de catégories de produits, et à l'intérieur de chaque élément, un second bloc Query doit afficher les trois derniers articles liés à cette catégorie. Au lieu de cela, les deux boucles semblent partager le même jeu de résultats, ou l'une écrase le contexte de l'autre.

## Symptôme : une boucle qui recopie l'autre

Concrètement, l'éditeur affiche un Query Loop parent qui parcourt correctement ses éléments, mais le Query Loop enfant, censé exécuter sa propre requête filtrée, ré-affiche à chaque itération le même article, ou reprend la pagination du parent au lieu de la sienne. Sur le front, le comportement peut différer de celui de l'éditeur, ce qui ajoute à la confusion : un aperçu qui semblait correct casse une fois la page publiée.

Ce n'est pas un bug isolé du cœur de WordPress, mais une conséquence directe du fonctionnement du contexte de bloc : chaque Query Loop transmet aux InnerBlocks qu'il contient un contexte nommé `postId`, `postType` et `queryId`, que les blocs enfants consomment pour savoir sur quel article ils opèrent.

## Diagnostic : un queryId non déclaré ou dupliqué

La cause la plus fréquente tient en un mot : `queryId`. Chaque bloc Query Loop doit recevoir un identifiant unique pour que WordPress sache distinguer sa pagination et son contexte de requête de ceux d'un autre bloc Query présent sur la même page. Quand deux Query Loop imbriqués portent, par accident ou par copier-coller de blocs, le même `queryId`, WordPress les traite comme une seule et même boucle logique du point de vue de la pagination, même si leurs requêtes diffèrent par ailleurs.

> L'essentiel à retenir : Le contexte queryId manquant fait hériter le mauvais article ; Un queryId distinct par bloc Query résout la confusion ; Le mode aperçu masque parfois le bug jusqu'à la publication

Pour vérifier cette hypothèse, l'inspection du code source enregistré du contenu (bouton « Code editor » de l'éditeur, ou export via WP-CLI) permet de lire directement l'attribut `queryId` de chaque commentaire de bloc Query :

```
<!-- wp:query {"queryId":0,"query":{"perPage":6,"postType":"produit"}} -->
  ...
  <!-- wp:query {"queryId":0,"query":{"perPage":3,"postType":"post"}} -->
  ...
  <!-- /wp:query -->
<!-- /wp:query -->
```

Ici, les deux boucles partagent `"queryId":0`, ce qui est la source directe du conflit observé.

### Un second piège : le contexte hérité du parent

Même avec des identifiants distincts, un bloc à l'intérieur d'un Query Loop enfant peut, s'il est mal configuré, continuer à lire le contexte `postId` du Query Loop parent plutôt que celui de sa propre boucle. Cela se produit typiquement quand un bloc personnalisé déclare son besoin de contexte via `usesContext` sans filtrer explicitement la source, et se contente du premier contexte disponible dans l'arbre.

## Correctif : réattribuer des identifiants et vérifier l'héritage

La correction se fait en deux temps. D'abord, réattribuer manuellement un `queryId` distinct à chaque bloc Query de la page, en réenregistrant chaque boucle depuis l'éditeur plutôt qu'en dupliquant un bloc existant. Ensuite, dans un bloc personnalisé consommant le contexte, vérifier que la lecture de `context.postId` se fait bien à l'intérieur du bon niveau d'InnerBlocks, sans remonter accidentellement au parent.

1. Supprimer puis réinsérer le Query Loop enfant plutôt que de le dupliquer, pour forcer l'attribution d'un nouvel identifiant.
2. Contrôler dans le code source enregistré que les deux valeurs de `queryId` diffèrent bien.
3. Republier la page et comparer l'aperçu de l'éditeur au rendu réellement servi sur le front, pas seulement à l'aperçu interne.

## Prévention : un identifiant explicite dès la conception

Sur un projet qui prévoit dès le départ plusieurs boucles imbriquées, il est plus sûr de documenter dans le code de l'extension ou du thème quel `queryId` est réservé à quelle zone de la page, plutôt que de laisser l'éditeur les attribuer automatiquement au fil des insertions et suppressions de blocs.

## En résumé

Un chevauchement entre deux Query Loop imbriqués se résume presque toujours à un identifiant de requête partagé par erreur, ou à un contexte mal filtré dans un bloc personnalisé. Le réflexe à adopter reste le même : inspecter le code source enregistré avant de suspecter un bug du cœur, et vérifier systématiquement que chaque boucle porte bien son propre `queryId`.
