vendredi 25 septembre 2026

À propos

Contact

Headless & API

Contenu flexible ACF en headless : des pages construites par sections

Modéliser des pages entières avec un champ flexible ACF, les exposer en GraphQL et rendre chaque section comme un composant front dédié.

Par Clément Hadrot • 2 octobre 2023 • 4 min de lecture • Aucun commentaire
Contenu flexible ACF en headless : des pages construites par sections

Pour une agence de voyage, chaque page d’atterrissage combinait un bandeau d’accroche, une grille de destinations, un bloc de témoignages, un tableau de tarifs et un appel à l’action final — mais jamais dans le même ordre, et jamais tous en même temps. Plutôt que de créer une page par gabarit rigide, le champ flexible d’Advanced Custom Fields s’est imposé naturellement : chaque page devient une pile de sections que l’éditeur assemble librement.

Reste à exposer cette structure proprement en GraphQL, puis à la rendre côté front sans transformer le composant de page en usine à conditions imbriquées. Voici comment on a construit ce pont.

Modéliser le champ flexible côté back-office

Le champ flexible sections_page est déclaré avec cinq dispositions : accroche, grille_destinations, temoignages, tableau_tarifs et appel_action. Chaque disposition regroupe uniquement les sous-champs dont elle a besoin, sans rien mutualiser artificiellement avec les autres.

Exposer chaque disposition comme un type GraphQL distinct

Avec WPGraphQL for ACF, chaque disposition d’un champ flexible devient automatiquement un type GraphQL séparé, regroupés dans une union exposée sur le champ parent. Il suffit d’activer show_in_graphql sur le groupe de champs et de nommer proprement le champ flexible pour que le schéma génère cette structure :

{
  page(id: "voyage-vietnam", idType: URI) {
    sectionsPage {
      __typename
      ... on Page_Sectionspage_SectionsPage_GrilleDestinations {
        destinations { titre image { sourceUrl } }
      }
      ... on Page_Sectionspage_SectionsPage_TableauTarifs {
        lignesTarifs { formule prix }
      }
    }
  }
}

Le champ __typename est la clé de voûte de tout l’exercice : c’est lui que le front va lire pour savoir quel composant instancier, section par section.

L'essentiel à retenir : Un champ flexible = une page composée de blocs métier ; Chaque disposition devient un type GraphQL distinct ; Le front choisit le composant par un simple aiguillage

Rendre chaque section côté front

Plutôt qu’un unique composant bardé de conditions, on construit un registre qui associe chaque __typename à son composant :

const registreSections = {
  Page_Sectionspage_SectionsPage_Accroche: BlocAccroche,
  Page_Sectionspage_SectionsPage_GrilleDestinations: BlocGrilleDestinations,
  Page_Sectionspage_SectionsPage_Temoignages: BlocTemoignages,
  Page_Sectionspage_SectionsPage_TableauTarifs: BlocTarifs,
  Page_Sectionspage_SectionsPage_AppelAction: BlocAppelAction,
};

function PageComposee({ sections }) {
  return sections.map((section, i) => {
    const Composant = registreSections[section.__typename];
    return Composant ? <Composant key={i} {...section} /> : null;
  });
}

Ajouter une sixième disposition ne demande alors qu’une entrée supplémentaire dans ce registre, jamais une modification du composant de page lui-même.

Un piège fréquent : les noms de type qui changent

Le nom du type généré dépend directement du nom du groupe de champs et de la disposition tels que déclarés dans ACF. Renommer un champ flexible en cours de projet casse silencieusement tous les __typename attendus côté front, sans erreur explicite tant que la disposition existe encore quelque part dans le schéma. Fixer les noms dès la modélisation initiale évite ce genre de mauvaise surprise en cours de route.

Ordonner les sections sans se tromper

  1. Le champ flexible renvoie déjà les sections dans l’ordre défini par l’éditeur dans le back-office.
  2. Le front ne doit surtout pas retrier ce tableau : l’ordre éditorial fait partie du contenu, pas un détail d’affichage.
  3. Seules les dispositions reconnues par le registre sont rendues, les autres sont ignorées silencieusement plutôt que de casser la page.

Un champ flexible mal borné devient vite un fourre-tout de vingt dispositions que plus personne n’ose supprimer. Mieux vaut restreindre volontairement le nombre de dispositions disponibles à ce que la charte éditoriale prévoit réellement.

Notre verdict

Le couple champ flexible et union GraphQL donne à l’équipe éditoriale une vraie liberté de composition, tout en laissant au front une structure prévisible à consommer. C’est l’un des rares cas où la flexibilité maximale côté back-office ne se traduit pas par du code front fragile, à condition de garder un registre de composants clair et des noms de disposition stables dans le temps.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi