Une question revient systématiquement en formation interne quand on aborde l’Interactivity API : « d’où vient réellement la donnée que je lis avec state.quelquechose côté JavaScript ? ». La confusion est légitime, car cette API fait cohabiter trois notions proches mais distinctes — l’état global du store, le contexte local d’une instance, et les valeurs dérivées calculées à la volée — sans que la syntaxe seule permette toujours de les distinguer au premier regard.
Cette notion mérite d’être posée clairement une bonne fois, car mal comprise, elle mène à des bugs difficiles à diagnostiquer : une donnée qui semble partagée entre deux instances du même bloc alors qu’elle devrait être isolée, ou l’inverse.
L’état global, défini côté serveur
L’état global d’un store s’initialise côté PHP avec wp_interactivity_state(), appelée dans le rendu du bloc. Cette fonction sérialise les données fournies dans une balise <script type="application/json"> injectée dans le HTML, que le module d’interactivité côté client lit au démarrage pour hydrater son store JavaScript.
<?php
wp_interactivity_state( 'agence/compteur-panier', array(
'articlesEnStock' => (int) get_post_meta( get_the_ID(), 'stock', true ),
) );
?>
<div data-wp-interactive="agence/compteur-panier">
<p>Stock disponible : <span data-wp-text="state.articlesEnStock"></span></p>
</div>
Cet état est global au store : si plusieurs instances du même bloc apparaissent sur la page, elles partagent la même donnée state.articlesEnStock, sauf si chaque appel PHP fusionne des valeurs différentes selon le contexte de rendu — un piège fréquent quand on s’attend, à tort, à un état isolé par bloc.
Le contexte, isolé par instance
Pour une donnée qui doit rester propre à chaque instance d’un bloc répété sur la page — un accordéon ouvert indépendamment des autres, par exemple — c’est le contexte, pas l’état global, qui s’utilise. Il se définit avec la directive data-wp-context directement dans le HTML rendu par le bloc, sous forme de JSON inline :
<div
data-wp-interactive="agence/accordeon"
data-wp-context='{ "ouvert": false }'
>
<button data-wp-on--click="actions.basculer" data-wp-bind--aria-expanded="context.ouvert">
Question fréquente
</button>
<p data-wp-bind--hidden="!context.ouvert">Réponse…</p>
</div>
Côté module de vue, getContext() lit et modifie ce contexte local à l’instance courante uniquement — deux accordéons sur la même page, chacun avec son propre data-wp-context, restent totalement indépendants l’un de l’autre, contrairement à l’état global.
import { store, getContext } from '@wordpress/interactivity';
store( 'agence/accordeon', {
actions: {
basculer() {
const context = getContext();
context.ouvert = ! context.ouvert;
},
},
} );

Les getters, pour dériver sans dupliquer
Un getter est une propriété calculée définie dans le store, qui dérive une valeur à partir de l’état ou du contexte plutôt que de la stocker séparément — évitant ainsi de synchroniser manuellement deux données qui devraient toujours rester cohérentes entre elles.
store( 'agence/compteur-panier', {
state: {
get messageStock() {
return state.articlesEnStock > 0
? `${ state.articlesEnStock } en stock`
: 'Rupture de stock';
},
},
} );
Utilisé ainsi dans le HTML, data-wp-text="state.messageStock" se recalcule automatiquement à chaque changement de state.articlesEnStock, sans qu’aucune action n’ait besoin de mettre à jour ce message explicitement — un principe proche des propriétés calculées qu’on retrouve dans d’autres frameworks réactifs, appliqué ici aux stores de l’Interactivity API.
Récapitulatif des trois notions
| Notion | Portée | Origine | API de lecture côté JS |
|---|---|---|---|
| State (état) | Globale au store, partagée entre instances | wp_interactivity_state() côté PHP | state.xxx dans les directives, ou import { state } |
| Context (contexte) | Isolée par instance de bloc | data-wp-context dans le HTML | getContext() dans les actions/callbacks |
| Getter dérivé | Suit la portée de sa définition (state ou context) | Calculé, jamais sérialisé directement | Lecture identique à une propriété normale |
Le piège le plus fréquent
Utiliser state pour une donnée qui devrait être un context isolé — typiquement, initialiser un attribut « ouvert/fermé » d’un accordéon via wp_interactivity_state() plutôt que via data-wp-context — fait que tous les accordéons de la page s’ouvrent ou se ferment simultanément, un bug qui surprend souvent en revue de code car le code fonctionne parfaitement… tant qu’il n’y a qu’une seule instance du bloc sur la page testée.
La règle qu’on applique systématiquement en formation : si la donnée doit être partagée entre toutes les instances d’un bloc sur la page, c’est un
state; si elle doit rester propre à chaque instance, c’est uncontext. Cette seule question tranche l’immense majorité des cas d’hésitation.
En résumé
L’Interactivity API distingue volontairement l’état global, sérialisé côté serveur et partagé, du contexte local, déclaré en HTML et isolé par instance, avec les getters comme troisième brique pour dériver des valeurs sans dupliquer de donnée source. Une fois cette distinction posée clairement, la grande majorité des bugs de bloc interactif qui semblaient mystérieux s’expliquent immédiatement par un mauvais choix entre ces deux portées.