vendredi 25 septembre 2026

À propos

Contact

Blocs Gutenberg

useInnerBlocksProps : la manière moderne de composer un conteneur

Le composant InnerBlocks historique impose une structure DOM figée. Le hook qui l'a remplacé rend enfin possible ce qui semblait hors de portée : un conteneur flexible.

Par Clément Hadrot • 27 juillet 2022 • 4 min de lecture • Aucun commentaire
useInnerBlocksProps : la manière moderne de composer un conteneur

Un développeur maintenant un bloc « Accordéon » depuis plusieurs années se heurtait à une limitation persistante : le composant InnerBlocks, tel qu’il l’utilisait depuis ses débuts avec Gutenberg, imposait systématiquement son propre élément div englobant les blocs enfants, un wrapper supplémentaire qui venait s’intercaler entre le conteneur du bloc et son contenu réel. Pour un composant d’accordéon dont chaque ligne devait respecter une structure CSS précise (flexbox avec un ordre d’éléments spécifique), ce wrapper superflu cassait systématiquement la mise en page, obligeant à des contournements CSS peu satisfaisants.

Le hook useInnerBlocksProps, apparu avec l’apiVersion 2 de l’éditeur de blocs, répond exactement à ce problème en permettant de fusionner les props du conteneur de blocs enfants directement sur l’élément DOM de son choix, sans imposer de wrapper intermédiaire.

Le problème du composant InnerBlocks historique

Avec l’ancienne approche, le composant InnerBlocks se plaçait comme un enfant du conteneur du bloc, générant automatiquement son propre élément DOM :

// Ancienne approche : un wrapper supplémentaire est généré
export default function Edit() {
    const blockProps = useBlockProps();
    return (
        <div { ...blockProps }>
            <InnerBlocks />
        </div>
    );
}

Le HTML final comportait alors deux niveaux de div imbriqués, l’un pour le bloc lui-même, l’autre généré par InnerBlocks, une structure rarement souhaitée quand le CSS attendait un contact direct entre le conteneur et ses enfants.

La fusion de props avec useInnerBlocksProps

import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';

export default function Edit() {
    const blockProps = useBlockProps();
    const innerBlocksProps = useInnerBlocksProps( blockProps, {
        template: [ [ 'mon-agence/ligne-accordeon' ] ],
        templateLock: false,
    } );
    return <div { ...innerBlocksProps } />;
}

Ici, un seul élément div porte à la fois les props du bloc lui-même et celles nécessaires à l’affichage des blocs enfants : plus aucun wrapper intermédiaire ne s’intercale, le CSS flexbox de l’accordéon s’applique enfin exactement comme prévu.

L'essentiel à retenir : Le hook fusionne les props du conteneur et des blocs enfants ; Il élimine le wrapper supplémentaire imposé par le composant historique ; La migration reste progressive, sans réécriture totale du bloc

Le même hook côté save()

La fonction save() suit exactement le même principe, avec l’appel équivalent useInnerBlocksProps.save(), qui reçoit les props statiques du conteneur plutôt que celles générées par useBlockProps côté édition.

import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';

export default function save() {
    const blockProps = useBlockProps.save();
    const innerBlocksProps = useInnerBlocksProps.save( blockProps );
    return <div { ...innerBlocksProps } />;
}

Migrer un bloc existant sans tout réécrire

La migration depuis l’ancien composant InnerBlocks ne nécessite pas de réécriture complète du bloc : l’essentiel du changement se limite au remplacement du composant JSX par l’appel au hook, en conservant les mêmes options de template et de verrouillage déjà en place. Le passage à apiVersion: 3 dans block.json, généralement effectué en parallèle, active par ailleurs l’éditeur en mode iframe, ce qui impose de vérifier que les styles CSS chargés côté éditeur restent bien disponibles dans ce nouveau contexte.

  • Le hook accepte les mêmes options que l’ancien composant : template, templateLock, allowedBlocks.
  • Un seul élément DOM porte désormais toutes les props nécessaires, plus besoin d’imbrication artificielle.
  • La rétrocompatibilité avec le contenu déjà publié reste assurée tant que le balisage final produit par save() reste identique.

Un point de vigilance : la validation de contenu

Un changement de structure DOM entre l’ancienne et la nouvelle version de save() déclenche une invalidation de tout le contenu déjà publié avec ce bloc, l’éditeur détectant une différence entre le HTML stocké et celui que produirait la nouvelle fonction. Une déprecation correctement déclarée via la propriété deprecated du bloc reste indispensable pour migrer en douceur sans casser le contenu existant.

Ne migrez jamais un save() en production sans vérifier, sur un échantillon réel de contenu publié, que l’éditeur ne signale aucun bloc invalide après le déploiement.

Pour aller plus loin

useInnerBlocksProps a largement remplacé l’ancien composant dans la documentation officielle et dans les blocs natifs de WordPress eux-mêmes, à commencer par le bloc Groupe et le bloc Colonnes. Pour tout nouveau bloc composé, il n’y a aujourd’hui plus aucune raison de repartir sur l’ancienne approche, sinon la simple habitude d’un code existant qui fonctionne encore, en attendant sa prochaine occasion de refonte.

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