Le champ ACF Flexible Content d’un client du secteur immobilier compte aujourd’hui dix mises en page distinctes : un bloc « Bien en avant », un « Comparatif de quartiers », un « Formulaire d’estimation », et sept autres. Interrogé naïvement depuis WPGraphQL, ce champ génère une requête GraphQL de plus de deux cents lignes, remplie d’imbrications de fragments en ligne, devenue illisible pour quiconque rejoint le projet en cours de route.
Cet article ne traite pas du contenu flexible côté API REST, un sujet distinct déjà couvert ailleurs sur ce blog. Il porte spécifiquement sur la manière de structurer une requête WPGraphQL contre un champ Flexible Content à variantes multiples, sans sacrifier la lisibilité.
Le problème : une union de types qui grossit vite
Avec WPGraphQL et l’extension WPGraphQL for ACF, un champ Flexible Content est exposé comme une liste d’un type d’union, un objet différent par mise en page possible. Interroger ce champ oblige à utiliser la syntaxe ... on NomDuType pour chaque variante, faute de quoi seuls les champs communs (souvent aucun) sont retournés. Sans organisation, la requête finit par ressembler à ceci, ici tronquée pour l’exemple :
query Page($id: ID!) {
page(id: $id, idType: URI) {
blocsFlexibles {
contenuFlexible {
... on Page_Contenuflexible_ContenuFlexible_BienEnAvant {
fieldGroupName
titre
bien { ... on Bien { title } }
}
... on Page_Contenuflexible_ContenuFlexible_ComparatifQuartiers {
fieldGroupName
quartiers { nom statistiques }
}
# ... huit autres blocs, chacun sur dix à vingt lignes
}
}
}
}
La méthode : un fragment nommé par mise en page
La solution consiste à extraire chaque variante dans un fragment GraphQL nommé, déclaré une seule fois puis simplement référencé dans la requête principale :
fragment BienEnAvant on Page_Contenuflexible_ContenuFlexible_BienEnAvant {
fieldGroupName
titre
bien {
... on Bien {
title
prix
surface
}
}
}
fragment ComparatifQuartiers on Page_Contenuflexible_ContenuFlexible_ComparatifQuartiers {
fieldGroupName
quartiers {
nom
statistiques
}
}
query Page($id: ID!) {
page(id: $id, idType: URI) {
blocsFlexibles {
contenuFlexible {
...BienEnAvant
...ComparatifQuartiers
}
}
}
}

Organiser les fragments par fichier côté front
Sur ce projet, chaque fragment vit désormais dans son propre fichier .graphql, à côté du composant React qui affiche la mise en page correspondante :
blocs/
├── bien-en-avant/
│ ├── BienEnAvant.jsx
│ └── bien-en-avant.fragment.graphql
├── comparatif-quartiers/
│ ├── ComparatifQuartiers.jsx
│ └── comparatif-quartiers.fragment.graphql
└── ...
L’outil graphql-codegen assemble ensuite ces fragments avec la requête principale au moment du build, ce qui garde la requête racine courte tout en générant des types TypeScript précis pour chaque bloc, sans jamais toucher à un fichier monolithique.
Le champ fieldGroupName, indispensable côté front
Chaque objet retourné par l’union porte un champ fieldGroupName qui identifie sans ambiguïté la mise en page concernée. Côté React, ce champ pilote le rendu conditionnel du bon composant, sans avoir à deviner le type à partir de la forme des données :
function BlocsFlexibles({ blocs }) {
return blocs.map((bloc, i) => {
switch (bloc.fieldGroupName) {
case 'Page_Contenuflexible_ContenuFlexible_BienEnAvant':
return <BienEnAvant key={i} data={bloc} />
case 'Page_Contenuflexible_ContenuFlexible_ComparatifQuartiers':
return <ComparatifQuartiers key={i} data={bloc} />
default:
return null
}
})
}
Ce que cette organisation apporte réellement
- L’ajout d’une onzième mise en page se fait par un nouveau fragment isolé, sans toucher aux neuf existants.
- Un développeur qui rejoint le projet comprend un fragment de dix lignes bien plus vite qu’une requête de deux cents lignes.
- Les erreurs de typage générées par
graphql-codegenpointent directement vers le fragment fautif, jamais vers un bloc noir de deux cents lignes.
Une requête GraphQL trop longue n’est jamais une fatalité liée au champ interrogé : c’est presque toujours un signe qu’il manque une étape de découpage en fragments.
En résumé
Un champ Flexible Content à dix variantes ou plus n’a rien d’ingérable en WPGraphQL, à condition de refuser la tentation de tout écrire dans une seule requête géante. Un fragment par mise en page, un fichier par composant, et la structure reste lisible même quand le nombre de blocs continue de grandir au fil des besoins du client.