Skip to content

Tout pour WordPress, le développement web — et plus encore

🛠 Inclusion correcte de JavaScript dans les thèmes WordPress

🛠 Inclusion correcte de JavaScript dans les thèmes WordPress

Votre galerie WordPress a cessé de fonctionner après une mise à jour. Cela vous semble familier?

La cause est presque toujours du JavaScript lié directement dans header.php, sans hooks, sans dépendances, sans tenir compte du fait qu’un plugin de cache peut modifier l’ordre de chargement. Un plugin charge jQuery, un autre charge sa propre version de jQuery, et votre script se retrouve entre les deux et plante avec $ is not defined.

En pratique, un seul appel à wp_enqueue_script au bon endroit suffit pour oublier les conflits définitivement. Voici un tour d’horizon complet: des erreurs de débutant aux stratégies defer/async et aux options de réglage fin apparues dans WordPress 6.6.

💡 Aperçu rapide:

  • N’insérez pas de balises script directement dans header.php ou footer.php: cela crée des conflits avec les plugins et casse les thèmes enfants
  • Enqueue le JavaScript via wp_enqueue_script dans functions.php avec le hook wp_enqueue_scripts: WordPress placera lui-même les balises dans head ou avant /body
  • Pour un court code inline, utilisez wp_add_inline_script, pas une balise script nue: cela préserve l’ordre d’exécution et donne aux plugins la possibilité d’intercepter le code
  • Sur WordPress 6.3+, spécifiez une stratégie defer ou async directement dans les paramètres d’appel, et à partir de 6.6, fetchpriority également
  • Déqueue les scripts tiers via wp_dequeue_script si un plugin ralentit votre site: la priorité du hook est déterminante

Comment le JavaScript est incorrectement ajouté à WordPress

Scénario typique: vous devez charger votre custom.js, et le développeur insère cette ligne dans header.php:

1<script src="<?php echo get_template_directory_uri(); ?>/js/custom.js"></script>

Cela semble fonctionner. Mais cette approche crée trois problèmes.

Conflits avec les plugins. Un plugin de cache combine les scripts dans un ordre différent, un plugin de minification renomme le fichier et casse le chemin. Si un autre plugin a déjà chargé jQuery et que vous le chargez à nouveau, double chargement et erreurs dans la console.

Impossible de surcharger via un thème enfant. Lors de l’utilisation d’un thème enfant, header.php est rarement copié. Si le script est codé en dur dans le header.php parent, le thème enfant ne peut pas le déqueue ni le remplacer sans copier le fichier entier, ce qui signifie que les modifications seront perdues lors de la mise à jour du thème parent.

Aucune dépendance. Le navigateur charge votre script avant jQuery, et vous obtenez $ is not defined. Le script se charge sur toutes les pages, même là où il n’est pas nécessaire, et les requêtes supplémentaires ralentissent le site.

La bonne méthode: wp_enqueue_script

WordPress fournit un système de file d’attente pour les scripts et les styles. Vous n’insérez pas <script> manuellement, mais vous enregistrez le script via PHP, spécifiez les dépendances et l’emplacement de chargement. WordPress place les balises dans <head> ou avant </body> lui-même.

Exemple minimal fonctionnel pour le functions.php de votre thème:

1/**
2 * Enqueue the main theme script.
3 */
4function mytheme_enqueue_scripts() {
5 wp_enqueue_script(
6 'mytheme-main', // $handle — unique name
7 get_template_directory_uri() . '/js/main.js', // $src — file path
8 array( 'jquery' ), // $deps — dependencies
9 '1.0.0', // $ver — version for cache busting
10 true // $in_footer — load in footer
11 );
12}
13add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_scripts' );

La fonction wp_enqueue_script accepte cinq paramètres. $handle, un identifiant unique: si un autre plugin a déjà enregistré un script avec le même handle, il n’y aura pas de chargement en double. $deps, un tableau de handles de dépendances: WordPress chargera les scripts requis avant le vôtre. $in_footer avec la valeur true place la balise <script> avant </body>, ce qui accélère le rendu de la page.

Note: get_template_directory_uri() pointe vers le dossier du thème parent. Dans un thème enfant, utilisez get_stylesheet_directory_uri(), l’URL pointera vers le dossier enfant, et votre script ne sera pas perdu lors de la mise à jour du thème parent.

Stratégies de chargement: defer, async et fetchpriority

À partir de WordPress 6.3, le paramètre $args accepte un tableau avec des réglages supplémentaires:

1wp_enqueue_script(
2 'mytheme-main',
3 get_template_directory_uri() . '/js/main.js',
4 array( 'jquery' ),
5 '1.0.0',
6 array(
7 'in_footer' => true,
8 'strategy' => 'defer',
9 )
10);

La stratégie defer indique au navigateur: «charge le script en parallèle, exécute après la construction du DOM». L’ordre d’exécution est garanti, les scripts avec defer s’exécutent dans l’ordre où ils ont été ajoutés au DOM. La stratégie async signifie «exécute dès que chargé», l’ordre n’est pas garanti. Pour les scripts de thème qui dépendent du DOM, choisissez defer.

À partir de WordPress 6.6, le tableau $args a gagné deux paramètres supplémentaires. fetchpriority contrôle la priorité de chargement ('high' ou 'low'), utile pour les scripts critiques qui doivent se charger avant les autres. module_dependencies accepte un tableau d’identifiants de modules pour l’import dynamique, c’est pour les scénarios avancés avec les modules ES. Important: lorsque vous spécifiez module_dependencies, le script doit se charger dans le footer (in_footer => true) ou avec la stratégie defer, sinon la carte d’import des modules ne sera pas prête lorsque le script s’exécutera.

Quels scripts sont déjà dans WordPress

WordPress enregistre des dizaines de bibliothèques JavaScript par défaut: jQuery, jQuery UI, Backbone, wp-api, MediaElement.js et d’autres. Liste complète dans la documentation officielle.

La règle principale: ne chargez jamais jQuery depuis un CDN comme Google ou cdnjs si votre thème fonctionne dans l’écosystème WordPress. WordPress fournit lui-même jQuery avec le handle jquery. Pour l’utiliser, spécifiez simplement array( 'jquery' ) dans les dépendances, WordPress chargera sa propre version testée pour la compatibilité avec l’ensemble du cœur.

Vous pouvez vérifier si une bibliothèque est enregistrée via wp_script_is():

1if ( wp_script_is( 'jquery-ui-datepicker', 'registered' ) ) {
2 // Library is available — just add to $deps
3}

Utilisation du hook wp_enqueue_scripts

Le hook wp_enqueue_scripts se déclenche sur le frontend. C’est dans celui-ci que les appels à wp_enqueue_script sont enveloppés. N’appelez pas la fonction directement dans le corps de functions.php sans hook, le script pourrait se charger avant que WordPress n’enregistre les bibliothèques système.

Pour la zone d’administration, utilisez un hook séparé:

1add_action( 'admin_enqueue_scripts', 'mytheme_admin_scripts' );
2function mytheme_admin_scripts( $hook_suffix ) {
3 // $hook_suffix contains the current admin page
4 if ( 'post.php' !== $hook_suffix ) {
5 return; // load script only on the post edit page
6 }
7 wp_enqueue_script( 'mytheme-admin', get_template_directory_uri() . '/js/admin.js', array(), '1.0', true );
8}

Le chargement conditionnel économise des ressources: un script pour une page d’options ne doit pas se charger sur toutes les pages d’administration. Le paramètre $hook_suffix est passé automatiquement par WordPress, utilisez-le.

Si un script est nécessaire à la fois sur le frontend et dans l’administration, accrochez une fonction aux deux:

1add_action( 'wp_enqueue_scripts', 'mytheme_global_scripts' );
2add_action( 'admin_enqueue_scripts', 'mytheme_global_scripts' );

Ajout de JavaScript inline: wp_add_inline_script

Tout le code ne mérite pas d’être placé dans un fichier séparé. Pour les courts extraits, les compteurs, les variables de configuration, les gestionnaires rapides, WordPress fournit wp_add_inline_script:

1function mytheme_inline_config() {
2 wp_enqueue_script( 'mytheme-main', get_template_directory_uri() . '/js/main.js', array(), '1.0', true );
3 wp_add_inline_script(
4 'mytheme-main',
5 'const MYTHEME_AJAX_URL = "' . admin_url( 'admin-ajax.php' ) . '";',
6 'before'
7 );
8}
9add_action( 'wp_enqueue_scripts', 'mytheme_inline_config' );

Le troisième paramètre, 'before' ou 'after', détermine où le code est inséré par rapport au script spécifié. C’est pratique pour passer des variables PHP à JavaScript: l’URL du gestionnaire AJAX, la clé nonce de sécurité, l’ID de l’article courant.

Détail important: wp_add_inline_script ne fonctionne qu’avec un script enregistré. Si vous passez un handle qui n’est pas dans la file d’attente, le code ne sera pas émis. Donc d’abord wp_enqueue_script, puis wp_add_inline_script.

Alternative pour les thèmes enfants: wp_head et wp_footer

Si vous travaillez dans un thème enfant et ne voulez pas créer de fichier séparé, vous pouvez émettre du code directement via les hooks wp_head (dans <head>) ou wp_footer (avant </body>):

1add_action( 'wp_footer', function() { ?>
2 <script>
3 ( function( $ ) {
4 'use strict';
5 $( function() {
6 // Your code here — DOM is already ready
7 } );
8 } ( jQuery ) );
9 </script>
10<?php } );

Cette méthode est plus courte mais moins flexible que wp_enqueue_script: pas de dépendances, de versionnage ni de possibilité de déqueue le script via un thème enfant. Utilisez-la pour de petites corrections lorsque vous ne voulez pas créer de fichier séparé.

Comment déqueue un script ajouté par un plugin ou un thème

Parfois, un plugin charge un script inutile sur toutes les pages et ralentit le site. Vous pouvez le supprimer via wp_dequeue_script:

1function mytheme_dequeue_plugin_scripts() {
2 if ( ! is_page( 'contacts' ) ) {
3 wp_dequeue_script( 'plugin-handle' );
4 }
5}
6add_action( 'wp_enqueue_scripts', 'mytheme_dequeue_plugin_scripts', 20 );

La priorité 20 (troisième argument de add_action) place votre fonction après l’enregistrement du plugin, sinon le handle ne sera pas encore dans la file d’attente. Vous pouvez trouver le handle d’un script via la console du navigateur: ouvrez la source de la page et trouvez l’attribut id sur la balise <script>, le handle correspond généralement à l’id sans le suffixe -js.

Si vous devez remplacer complètement un script, déregistrez d’abord l’ancien via wp_deregister_script, puis enregistrez le nouveau:

1function mytheme_replace_script() {
2 wp_deregister_script( 'old-handle' );
3 wp_enqueue_script( 'old-handle', get_template_directory_uri() . '/js/replacement.js', array(), '2.0', true );
4}
5add_action( 'wp_enqueue_scripts', 'mytheme_replace_script', 20 );

Avant de telles opérations, faites une sauvegarde complète du site. Remplacer les scripts des plugins est un chemin direct vers des fonctionnalités cassées si vous ne testez pas dans un environnement de staging.

La vidéo ci-dessus montre un découpage étape par étape de la mise en file d’attente de CSS et JavaScript dans un thème WordPress via wp_enqueue_script et wp_enqueue_style. Si vous débutez avec les hooks, commencez par elle, puis revenez à ce guide écrit pour les détails.

⁉️🤔 Foire aux questions

Est-il obligatoire d’utiliser wp_enqueue_script pour chaque fichier js?

En pratique, oui, pour tous les scripts chargés globalement. Pour un script qui fonctionne sur une seule page et est généré dynamiquement, il est acceptable d’insérer <script> directement dans le template. Mais dès que vous avez deux scripts ou plus, la file d’attente via wp_enqueue_script vous fait gagner des heures de débogage.

Quelle est la différence entre wp_register_script et wp_enqueue_script?

wp_register_script enregistre seulement un script dans le système (définit le handle, le chemin, les dépendances) mais n’émet pas la balise sur la page. wp_enqueue_script enregistre ET met immédiatement en file d’attente pour l’émission. La séparation est utile lorsque le script n’est pas toujours nécessaire: enregistrez une fois dans functions.php, et appelez wp_enqueue_script('my-handle') uniquement sur les pages requises.

Puis-je charger des scripts depuis un CDN externe?

Techniquement, oui, passez l’URL complète comme deuxième paramètre. Mais pour jQuery et les autres bibliothèques du cœur WordPress, c’est une mauvaise pratique: WordPress les inclut déjà et teste leur compatibilité. Un CDN externe se justifie pour les services tiers comme Google Analytics, reCAPTCHA, les widgets de chat. Là, spécifiez l’URL telle quelle.

Comment vérifier qu’un script s’est effectivement chargé?

Ouvrez les outils de développement (F12), onglet Réseau, filtrez par JS et rafraîchissez la page. Votre fichier doit apparaître dans la liste avec un code de statut 200. Si le script est absent, vérifiez que le hook wp_enqueue_scripts se déclenche sur cette page et que le chemin du fichier est correct. Pour le débogage, affichez get_template_directory_uri() séparément et comparez l’URL.

Que faire si les scripts cessent de fonctionner après une mise à jour du thème?

Très probablement, la mise à jour a écrasé votre functions.php. La solution est un thème enfant: créez-en un, déplacez-y vos fonctions et activez-le. Après cela, les mises à jour du thème parent laisseront votre code intact.

Que signifie l’erreur «$ is not defined» lors de l’utilisation de jQuery?

WordPress charge jQuery en mode noConflict, la variable $ n’est pas occupée par jQuery pour éviter les conflits avec d’autres bibliothèques. Utilisez le nom complet jQuery au lieu de $ ou enveloppez le code dans une fonction auto-invoquante: (function($) { ... })(jQuery);.

Cela vaut-il la peine de s’embêter avec wp_enqueue_script pour deux ou trois scripts?

Si vous avez plus d’un plugin sur le site, cela en vaut la peine. La file d’attente de scripts de WordPress est conçue de telle sorte qu’un plugin qui charge jQuery directement casse la moitié du site au moment où vous installez un plugin de cache. wp_enqueue_script élimine toute cette classe de problèmes.

Pour un thème de cinq fichiers, utilisez wp_enqueue_script. Pour un court extrait sur une page spécifique, wp_add_inline_script ou le hook wp_footer feront l’affaire. Mais dès que vous avez deux scripts ou plus, revenez à la file d’attente. Une heure passée à une mise en file d’attente correcte maintenant vous épargne une soirée de débogage après la prochaine mise à jour de WordPress.