Avant l’existence de viewScript, charger un script front seulement pour les pages contenant un bloc précis demandait d’écrire soi-même une fonction PHP vérifiant, via has_block(), la présence du bloc dans le contenu de l’article, puis d’enregistrer conditionnellement le script correspondant. Ce code, souvent copié-collé d’un bloc à l’autre, devient inutile dès que block.json prend en charge cette logique nativement.
La déclaration dans block.json
{
"name": "mon-projet/carrousel-avis",
"editorScript": "file:./index.js",
"script": "file:./script.js",
"viewScript": "file:./view.js"
}
Trois clés distinctes, trois usages différents. editorScript ne se charge que dans l’éditeur, jamais sur le front public. script se charge à la fois dans l’éditeur et sur le front, ce qui convient à une logique partagée entre les deux contextes. viewScript ne se charge que sur le front public, et seulement sur les pages où le bloc est réellement présent dans le contenu — jamais dans l’éditeur, jamais sur une page qui ne contient pas ce bloc.
Pourquoi ça change concrètement la performance

Sur un site avec dix blocs personnalisés, chacun avec son script d’interactivité front (un carrousel, un compteur animé, une carte interactive), sans ce mécanisme, un développeur devrait soit charger tous les scripts sur toutes les pages — un gâchis évident de requêtes et de poids JavaScript — soit écrire manuellement dix fonctions PHP de vérification conditionnelle avec has_block(). viewScript traite ce cas nativement, page par page, sans code PHP supplémentaire à maintenir.
// Ce que WordPress fait automatiquement en interne,
// sans qu'aucun code équivalent ne soit à écrire :
if ( has_block( 'mon-projet/carrousel-avis' ) ) {
wp_enqueue_script( 'mon-projet-carrousel-avis-view-script' );
}
Le fichier .asset.php et les dépendances
Quand le script est compilé via @wordpress/scripts, un fichier view.asset.php est généré automatiquement à côté de view.js, listant les dépendances détectées (par exemple si le script importe une fonction de @wordpress/dom-ready) ainsi qu’un numéro de version basé sur un hachage du contenu, utile pour l’invalidation du cache navigateur :
<?php
return array(
'dependencies' => array(),
'version' => '3f2a91c8b7d4e5f6',
);
register_block_type, en lisant block.json, associe automatiquement ce fichier de dépendances au script enregistré, sans intervention manuelle supplémentaire.
Ce que viewScript ne fait pas
- Il ne charge pas le script à l’intérieur de l’éditeur : un script d’interactivité front qui manipule directement le DOM du navigateur n’a généralement pas de sens dans le contexte React de l’éditeur, et peut même y provoquer des erreurs s’il est chargé par erreur.
- Il ne remplace pas
wp_enqueue_scriptpour des scripts qui n’appartiennent pas à un bloc précis, comme un script global de thème. - Il ne gère pas le différé de chargement (
defer,async) automatiquement : ce réglage reste à ajouter séparément si nécessaire, via le filtrescript_loader_tagpar exemple.
Un cas d’usage typique : un compteur animé
Un bloc « statistique animée » qui incrémente visuellement un chiffre au défilement de la page illustre bien la séparation des rôles : editorScript gère l’édition de la valeur cible dans l’inspecteur, viewScript gère uniquement l’animation d’incrémentation, déclenchée par une observation d’intersection avec l’API native du navigateur, sans dépendance à React côté front.
// view.js — exécuté uniquement sur le front, uniquement si le bloc est présent
document.querySelectorAll( '.wp-block-mon-projet-statistique-animee' )
.forEach( ( element ) => {
// logique d'animation, sans React
} );
Sur nos projets, séparer systématiquement le script d’édition et le script front, même pour un bloc simple, évite de livrer inutilement du code React aux visiteurs du site public.
En résumé
viewScript reste sous-utilisé alors qu’il résout un besoin de performance réel avec une seule ligne de déclaration. Pour un bloc dont l’interactivité front devient plus ambitieuse, notamment avec une gestion d’état partagée entre plusieurs instances du même bloc sur une page, une approche différente devient pertinente — un sujet distinct de celui traité ici.