Comment afficher un score qui change dix fois par match sans qu’un supporteur n’ait à rafraîchir sa page manuellement ? Un club de handball amateur de troisième division voulait permettre à ses licenciés absents de suivre le score en direct depuis le site du club, sans filmer ni diffuser la moindre image — une simple mise à jour du score et du temps de jeu, saisie par un bénévole présent en tribune depuis son téléphone.
L’Interactivity API, stabilisée depuis WordPress 6.5, convenait parfaitement à ce besoin : elle permet de mettre à jour une portion de page sans rechargement complet, avec un code déclaratif plus simple à maintenir qu’un script personnalisé écrit à la main pour interroger un serveur en boucle.
Le formulaire de saisie côté bénévole
Un formulaire minimal, accessible uniquement aux utilisateurs disposant du rôle personnalisé marqueur, permet de saisir le score et le temps de jeu depuis un téléphone :
register_rest_route( 'club/v1', '/score', array(
'methods' => 'POST',
'callback' => 'club_mettre_a_jour_score',
'permission_callback' => function() {
return current_user_can( 'saisir_score_match' );
},
) );
function club_mettre_a_jour_score( $request ) {
$donnees = array(
'domicile' => (int) $request['scoreDomicile'],
'exterieur' => (int) $request['scoreExterieur'],
'temps' => sanitize_text_field( $request['tempsJeu'] ),
);
set_transient( 'club_score_match_courant', $donnees, HOUR_IN_SECONDS );
return $donnees;
}
Le bloc côté supporteur, branché sur l’Interactivity API

Le bloc club/score-direct déclare un état partagé et un callback d’interrogation périodique, sans écrire de boucle setInterval manuelle éparpillée dans le code :
import { store, getContext } from '@wordpress/interactivity';
store( 'club/score-direct', {
state: {
scoreDomicile: 0,
scoreExterieur: 0,
tempsJeu: '',
},
callbacks: {
rafraichirScore: async () => {
const reponse = await fetch( '/wp-json/club/v1/score' );
const donnees = await reponse.json();
const etat = store( 'club/score-direct' ).state;
etat.scoreDomicile = donnees.domicile;
etat.scoreExterieur = donnees.exterieur;
etat.tempsJeu = donnees.temps;
},
},
} );
Le render.php du bloc déclare la directive data-wp-init pour lancer une première lecture au chargement, puis une répétition toutes les dix secondes via une directive personnalisée basée sur setInterval, appelée depuis le callback enregistré :
<div
data-wp-interactive="club/score-direct"
data-wp-init="callbacks.demarrerRafraichissement"
>
<span data-wp-text="state.scoreDomicile">0</span>
-
<span data-wp-text="state.scoreExterieur">0</span>
<p data-wp-text="state.tempsJeu"></p>
</div>
Pourquoi dix secondes, ni plus ni moins
Le choix de l’intervalle d’interrogation a fait l’objet d’un arbitrage simple : un intervalle trop court, de l’ordre de deux ou trois secondes, multiplierait les requêtes vers le serveur sans réel bénéfice pour un score qui, dans un match de handball, ne change pas plus d’une fois par minute en moyenne. Un intervalle trop long, au-delà de vingt secondes, donnerait l’impression désagréable d’un site figé au moment précis d’un but. Dix secondes offrait le meilleur compromis mesuré lors des tests réalisés pendant deux matchs amicaux.
Ce que ce dispositif n’a jamais cherché à faire
- Aucune diffusion vidéo ou audio du match, exclue dès le départ du cahier des charges du club.
- Aucun historique détaillé des buts marqués minute par minute, seul le score courant étant affiché.
- Aucune notification push envoyée aux supporteurs à chaque changement de score — une évolution envisagée pour une saison ultérieure, mais hors périmètre de ce projet initial.
Un score affiché avec dix secondes de retard reste largement suffisant pour un supporteur absent : la valeur du dispositif tient dans sa fiabilité, pas dans une instantanéité parfaite.
Un point de vigilance sur la charge serveur
Avec plusieurs dizaines de supporteurs connectés simultanément pendant un match à enjeu, l’endpoint /wp-json/club/v1/score reçoit une requête par visiteur toutes les dix secondes. La lecture reposant uniquement sur un transient, déjà mis en cache d’objets par WordPress, cette charge reste largement absorbable sur l’hébergement mutualisé du club, sans qu’une mise en cache supplémentaire n’ait été nécessaire lors des tests en conditions réelles.
En résumé
L’Interactivity API permet de construire un affichage de score en direct sobre et fiable, sans diffusion vidéo ni infrastructure lourde : un formulaire de saisie réservé aux bénévoles habilités, un transient comme unique source de vérité, et un bloc qui s’auto-actualise à intervalle raisonnable. Pour un club amateur, cette simplicité compte autant que la technique elle-même.