Le problème / Le besoin
Si vous avez déjà collé un <script> “vite fait” dans le header et qu’un jour un plugin de cache, un builder ou une mise à jour WordPress a tout cassé, vous avez déjà rencontré le vrai sujet : charger CSS et JS proprement.
Sur WordPress 6.9.4 (avril 2026), la manière correcte de charger vos fichiers est d’utiliser l’API d’enqueue : wp_enqueue_scripts côté front, et admin_enqueue_scripts côté administration. C’est plus fiable, plus maintenable, et ça évite une grande partie des conflits liés à l’ordre de chargement, aux dépendances et au cache.
Ce guide s’adresse aux blogueurs débutants (et à ceux qui bricolent des snippets) qui veulent :
- charger un CSS et un JS sans casser le thème,
- les charger seulement là où il faut (page précise, type de contenu, shortcode),
- comprendre pourquoi “coller du code dans le header” est une mauvaise idée,
- éviter les erreurs classiques (hook inadapté, mauvais chemin, cache, dépendances).
Où coller le code de cet article : idéalement dans un mini-plugin (recommandé) ou un mu-plugin. À défaut, dans le functions.php d’un thème enfant (pas le thème parent). Ne modifiez jamais WordPress (le core).
Fonctions WordPress que vous allez utiliser (avec doc officielle) :
- Hook
wp_enqueue_scripts(action) : déclenche le moment où vous devez enregistrer/charger vos assets côté front. wp_enqueue_style(): charge une feuille de style.wp_enqueue_script(): charge un script JavaScript.wp_register_script()/wp_register_style(): enregistre un asset sans le charger tout de suite.wp_add_inline_script()/wp_add_inline_style(): ajoute du code inline de façon propre, attaché à un handle.
Résumé rapide
- Vous allez créer un petit plugin qui charge un CSS et un JS via
wp_enqueue_scripts. - Vous allez déclarer des dépendances (ex.
jquery) et une version pour mieux gérer le cache. - Vous allez charger les fichiers uniquement sur certaines pages (ex. page “Contact”) pour éviter d’alourdir tout le site.
- Vous allez apprendre quand utiliser
wp_add_inline_script()au lieu de coller un<script>dans le header. - Vous repartez avec une checklist de test + un tableau de diagnostic des pannes courantes.
Quand utiliser cette solution
- Vous ajoutez un petit script (menu sticky, tracking maison, animation légère) et vous voulez qu’il survive aux mises à jour.
- Vous avez un CSS “custom” que vous ne voulez pas coller dans l’interface du builder (ou dans le personnalisateur) pour garder une trace versionnée.
- Vous devez charger une librairie (slider, lightbox) sur une page ou un type de contenu seulement.
- Vous voulez éviter les conflits avec Divi 5 / Elementor / Avada et les plugins de cache qui réorganisent/minifient les scripts.
Quand ne PAS utiliser cette solution
Ne forcez pas du code si une solution native existe déjà :
- CSS “petites retouches” : si c’est 10 lignes, le “CSS additionnel” du personnalisateur peut suffire. Mais dès que ça grossit, passez à un fichier enqueue.
- Scripts de tracking (GA4, Matomo, Pixel) : utilisez un plugin de tracking fiable (ou Google Site Kit) plutôt que du code artisanal. Ça gère mieux le consentement et les changements d’API.
- Code spécifique à un bloc Gutenberg : si vous développez un bloc, la bonne pratique est d’enregistrer les assets via
block.json(build tooling) plutôt que viawp_enqueue_scripts. L’enqueue global reste valable, mais ce n’est pas le plus précis. - Vous travaillez sur un thème bloc (FSE) et vous voulez juste du style global : regardez aussi
theme.json. Ce n’est pas un remplaçant du JS, mais ça évite beaucoup de CSS custom.
Prérequis / avant de commencer
Versions et environnement
- WordPress : 6.9.4+
- PHP : 8.1+ (recommandé)
- Accès FTP/SFTP ou gestionnaire de fichiers (idéalement Git)
- Un site de test (staging) ou une sauvegarde restaurable
Sauvegarde et sécurité
- Faites une sauvegarde (fichiers + base de données) avant de toucher au code.
- Ne modifiez jamais un thème parent : une mise à jour écrasera vos changements.
- Évitez les plugins de “snippets” pour du JS/CSS complexe. J’ai souvent vu des sites tomber en écran blanc à cause d’un snippet mal copié, sans logs exploitables.
Outils utiles (optionnels mais pratiques)
- Un plugin de logs (ou l’accès aux logs serveur) pour voir les erreurs PHP.
- Un plugin de staging si votre hébergeur n’en propose pas.
- Les DevTools du navigateur (onglet Network/Console) pour vérifier le chargement.
L’approche naïve (et pourquoi l’éviter)
La version “débutant pressé” ressemble souvent à ça : on colle du HTML dans le header via un champ du thème, un widget, ou un plugin qui injecte du code.
<!-- Exemple à NE PAS reproduire -->
<link rel="stylesheet" href="/wp-content/themes/mon-theme/assets/custom.css">
<script src="https://example.com/ma-lib.js"></script>
<script>
// Code inline “vite fait”
console.log('Hello');
</script>
Pourquoi ça pose problème (dans la vraie vie)
- Ordre de chargement aléatoire : votre script peut s’exécuter avant jQuery, avant un script du builder, ou avant le DOM. Résultat : erreurs en console.
- Dépendances non déclarées : WordPress ne sait pas que votre script dépend de
jqueryou dewp-element. Vous perdez la gestion automatique. - Cache et minification : les plugins de performance regroupent/déplacent les scripts. Un
<script>collé “en dur” échappe souvent à leurs règles, ou pire, est déplacé sans dépendances. - Maintenance : quand vous changez de thème (ou de header builder), votre code disparaît. Dans mon expérience, c’est la cause n°1 des “mon site a perdu ses scripts” après refonte.
- Sécurité : injecter du JS via des champs admin peut ouvrir la porte à des XSS si plusieurs rôles ont accès à ces champs. Même si ce n’est “que vous”, ça finit souvent en “je donne l’accès à un rédacteur”.
La bonne approche — tutoriel pas à pas
Objectif : créer un petit plugin qui charge un CSS et un JS proprement, avec versioning, dépendances, et chargement conditionnel.
Étape 1 — Créez un mini-plugin (recommandé)
Créez un dossier : wp-content/plugins/bp-assets-loader/
Dans ce dossier, créez le fichier : bp-assets-loader.php
C’est ici que vous collez le code PHP (pas dans le header, pas dans un fichier du core).
Étape 2 — Ajoutez vos fichiers CSS/JS
Créez :
wp-content/plugins/bp-assets-loader/assets/css/bp-custom.csswp-content/plugins/bp-assets-loader/assets/js/bp-custom.js
Étape 3 — Enqueue via le hook wp_enqueue_scripts
Définition : un hook (crochet) est un point d’extension. Une action exécute du code à un moment donné (ici : quand WordPress prépare les scripts/styles du front). Un filtre modifie une valeur et la renvoie.
Vous allez accrocher (hook) une fonction sur l’action wp_enqueue_scripts.
Étape 4 — Chargez seulement là où c’est utile
Exemple concret : vous ne voulez charger votre JS que sur la page “Contact”. C’est un gain de performance réel.
Vous pouvez cibler :
- une page :
is_page('contact')ouis_page(123) - un article :
is_single() - un type de contenu :
is_singular('product')(WooCommerce) - un template :
is_page_template()
Étape 5 — Ajoutez du JS inline correctement (si nécessaire)
Si vous avez 5 lignes de configuration (une variable, un flag), ne collez pas un <script> dans le header. Utilisez wp_add_inline_script() attaché à votre handle. WordPress garantit ainsi l’ordre : inline après le script ciblé.
Code complet
Copiez-collez ce fichier dans wp-content/plugins/bp-assets-loader/bp-assets-loader.php, puis activez le plugin dans Extensions.
<?php
/**
* Plugin Name: BP Assets Loader (CSS/JS propre)
* Description: Exemple pédagogique : charger CSS/JS correctement via wp_enqueue_scripts (WordPress 6.9.4+).
* Version: 1.0.0
* Requires at least: 6.9
* Requires PHP: 8.1
* Author: Votre Nom
*/
declare(strict_types=1);
if (!defined('ABSPATH')) {
exit; // Sécurité : empêche l'accès direct au fichier.
}
/**
* Retourne une "version" basée sur la date de modification du fichier.
* Pratique en dev pour casser le cache sans changer le numéro de version à la main.
*
* En prod, vous pouvez préférer une version fixe (ex: 1.0.0) pour maîtriser le cache.
*/
function bp_assets_loader_file_version(string $filepath): string {
if (file_exists($filepath)) {
return (string) filemtime($filepath);
}
return '1.0.0';
}
/**
* Enqueue des assets front (site public).
*
* Hook : wp_enqueue_scripts
* Doc : https://developer.wordpress.org/reference/hooks/wp_enqueue_scripts/
*/
function bp_assets_loader_enqueue_front(): void {
// 1) Exemple de chargement conditionnel : on ne charge que sur la page "Contact".
// Remplacez 'contact' par le slug de votre page, ou utilisez l'ID (ex: is_page(123)).
if (!is_page('contact')) {
return;
}
$plugin_url = plugin_dir_url(__FILE__);
$plugin_path = plugin_dir_path(__FILE__);
$css_rel = 'assets/css/bp-custom.css';
$js_rel = 'assets/js/bp-custom.js';
$css_file = $plugin_path . $css_rel;
$js_file = $plugin_path . $js_rel;
$css_ver = bp_assets_loader_file_version($css_file);
$js_ver = bp_assets_loader_file_version($js_file);
// 2) Charger le CSS.
// wp_enqueue_style( $handle, $src, $deps, $ver, $media )
// Doc : https://developer.wordpress.org/reference/functions/wp_enqueue_style/
wp_enqueue_style(
'bp-custom-css',
$plugin_url . $css_rel,
array(), // Dépendances CSS (souvent vide).
$css_ver,
'all'
);
// 3) Charger le JS.
// wp_enqueue_script( $handle, $src, $deps, $ver, $args )
// Doc : https://developer.wordpress.org/reference/functions/wp_enqueue_script/
//
// Astuce : $args peut être un bool (in_footer) ou un tableau.
// Ici, on utilise un tableau pour être explicite.
wp_enqueue_script(
'bp-custom-js',
$plugin_url . $js_rel,
array(), // Dépendances : ajoutez 'jquery' si votre code dépend de jQuery.
$js_ver,
array(
'in_footer' => true, // Charge en bas de page : souvent meilleur pour les perfs.
'strategy' => 'defer' // Demande à WP d'ajouter defer si possible.
)
);
// 4) Exemple de configuration JS inline (propre).
// On évite de coller un <script> dans le header.
// Doc : https://developer.wordpress.org/reference/functions/wp_add_inline_script/
$config = array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'isDebug' => defined('WP_DEBUG') && WP_DEBUG,
);
// wp_json_encode assure un JSON valide.
$inline = 'window.BP_CUSTOM = ' . wp_json_encode($config) . ';';
// Le code inline sera placé APRÈS le script 'bp-custom-js'.
wp_add_inline_script('bp-custom-js', $inline, 'after');
}
add_action('wp_enqueue_scripts', 'bp_assets_loader_enqueue_front', 20);
Ajoutez ensuite un CSS minimal :
/* Fichier : assets/css/bp-custom.css */
.bp-contact-highlight {
border: 2px solid #1e1e1e;
padding: 12px;
}
Et un JS minimal :
// Fichier : assets/js/bp-custom.js
(function () {
// Exemple : vérifie que la config inline est présente
if (window.BP_CUSTOM && window.BP_CUSTOM.isDebug) {
console.log('BP_CUSTOM config:', window.BP_CUSTOM);
}
// Exemple : ajoute une classe sur un élément (à adapter à votre thème/builder)
var el = document.querySelector('.wpcf7'); // Contact Form 7, par exemple
if (el) {
el.classList.add('bp-contact-highlight');
}
})();
Explication du code
Explication simple (ce qui se passe)
- WordPress arrive au moment où il prépare les scripts/styles du front.
- Votre fonction
bp_assets_loader_enqueue_front()s’exécute grâce àadd_action(). - Elle vérifie si on est sur la page “Contact”. Si non : elle ne charge rien.
- Si oui : elle charge
bp-custom.cssetbp-custom.jsavec une version basée sur la date de modification du fichier. - Elle injecte une petite config JS via
wp_add_inline_script(), au bon endroit, sans bricolage dans le header.
Explication technique (les détails qui évitent les bugs)
add_action('wp_enqueue_scripts', ...) : vous accrochez une fonction sur une action. L’action wp_enqueue_scripts est le moment standard pour enqueuer côté front. Doc : add_action().
Priorité 20 : j’utilise souvent 20 (au lieu de 10) sur des sites avec builders/caches, parce que certains thèmes enqueuent beaucoup de choses à 10. Ça ne règle pas tout, mais ça réduit certains cas où votre style est immédiatement “écrasé” par un style chargé après.
plugin_dir_url(__FILE__) et plugin_dir_path(__FILE__) : évite les chemins codés en dur. Si vous migrez de domaine, de sous-dossier, ou si vous changez de structure, ça continue de fonctionner.
Versioning via filemtime() : WordPress ajoute ?ver=.... Les caches (navigateur/CDN) peuvent alors distinguer une nouvelle version. Doc PHP : filemtime().
strategy => defer : WordPress peut ajouter defer au script, ce qui retarde l’exécution jusqu’après le parsing HTML. Ça réduit les blocages. Si un plugin de cache réécrit les scripts, testez : certains cassent le defer sur des scripts dépendants. Référence : wp_enqueue_script().
Inline via wp_add_inline_script() : vous gardez l’ordre garanti. L’inline est attaché à un handle, donc s’il est désactivé (par condition), l’inline ne sort pas non plus. C’est exactement ce que vous voulez.
Pourquoi “ne jamais coller un script dans le header” (version terrain)
- Vous perdez le contrôle des dépendances et de l’ordre.
- Vous vous exposez à des doubles chargements (ex. deux fois la même librairie).
- Vous rendez le debug plus pénible : “ce script vient d’où ?” devient une chasse au trésor.
- Vous augmentez le risque de XSS si ce code est éditable via l’admin par plusieurs rôles.
Variantes et cas d’usage
Variante 1 — Charger partout, mais seulement si l’utilisateur est connecté
Pratique pour un outil de debug visuel réservé à vous.
function bp_assets_loader_enqueue_for_logged_in(): void {
if (!is_user_logged_in()) {
return;
}
wp_enqueue_style(
'bp-debug-css',
plugin_dir_url(__FILE__) . 'assets/css/bp-debug.css',
array(),
'1.0.0'
);
}
add_action('wp_enqueue_scripts', 'bp_assets_loader_enqueue_for_logged_in', 20);
Variante 2 — Déclarer une dépendance à jQuery (si vous en avez vraiment besoin)
En 2026, je conseille de viser du JS “vanilla” quand c’est possible. Mais certains scripts legacy utilisent jQuery.
wp_enqueue_script(
'bp-custom-js',
$plugin_url . $js_rel,
array('jquery'), // Dépendance déclarée
$js_ver,
array(
'in_footer' => true,
'strategy' => 'defer',
)
);
Variante 3 — Charger un script uniquement quand un shortcode est présent
Cas fréquent : vous avez un shortcode [bp_map] et vous voulez charger la librairie de carte seulement quand il apparaît.
Approche simple : détecter la présence dans le contenu du post courant. Attention : si votre builder n’utilise pas le contenu WP classique, cette méthode peut échouer (voir section compatibilité builders).
function bp_assets_loader_enqueue_when_shortcode(): void {
if (!is_singular()) {
return;
}
global $post;
if (!$post instanceof WP_Post) {
return;
}
if (!has_shortcode($post->post_content, 'bp_map')) {
return;
}
wp_enqueue_script(
'bp-map-js',
plugin_dir_url(__FILE__) . 'assets/js/bp-map.js',
array(),
'1.0.0',
array('in_footer' => true)
);
}
add_action('wp_enqueue_scripts', 'bp_assets_loader_enqueue_when_shortcode', 20);
Compatibilité Divi 5 / Elementor / Avada
Divi 5
Divi peut générer du contenu via son propre rendu. Deux points que je vois souvent :
- La détection de shortcode via
has_shortcode()peut être insuffisante si le contenu est stocké différemment. - Divi peut optimiser/minifier et changer l’ordre des scripts.
Conseil pratique : privilégiez les conditions basées sur la page (slug/ID) plutôt que sur le contenu, quand c’est un site 100% builder.
Elementor
Elementor charge déjà beaucoup d’assets. Pour éviter d’alourdir :
- chargez votre CSS/JS seulement sur les pages concernées (
is_page()), - utilisez
deferet testez la console, - évitez de charger une seconde fois une librairie déjà fournie par Elementor.
Si vous devez absolument charger un script uniquement quand un widget Elementor est présent, le plus fiable est souvent de lier votre asset à un template/page précise, ou d’implémenter un petit plugin Elementor (niveau plus avancé).
Avada (Fusion Builder)
Avada a ses propres optimisations et peut concaténer des scripts. J’ai souvent vu :
- un script chargé “en dur” dans le header qui se retrouve exécuté avant le HTML et échoue,
- des scripts déplacés en footer sans dépendances correctes.
Avec l’enqueue WordPress, vous gardez une base propre. Si Avada “optimise trop”, désactivez temporairement ses options de performance pour isoler le problème, puis réactivez une à une.
Vérifications après mise en place
Checklist rapide
- La page ciblée (ex. “Contact”) charge bien vos fichiers : ouvrez DevTools > Network > filtrez par “bp-custom”.
- Votre CSS s’applique : vérifiez dans l’inspecteur que la règle vient bien de
bp-custom.css. - Votre JS s’exécute : regardez la console (le
console.logen mode debug). - Le script est bien en bas de page : “View Source” ou onglet Elements, cherchez
bp-custom.js. - Après modification d’un fichier, la query string
?ver=...change (si vous utilisezfilemtime).
Tableau de diagnostic (symptômes fréquents)
| Symptôme | Cause probable | Vérification | Solution |
|---|---|---|---|
| Le CSS/JS ne se charge pas du tout | Plugin non activé, mauvais chemin, condition is_page() fausse |
WP Admin > Extensions, DevTools > Network | Activez le plugin, vérifiez slug/ID, vérifiez assets/ et les noms de fichiers |
| Le fichier est en 404 | Chemin incorrect, fichier manquant, mauvaise casse (Linux) | Ouvrez l’URL du fichier dans le navigateur | Corrigez le chemin, renommez correctement, vérifiez la casse |
| Le JS se charge mais “ne fait rien” | Sélecteur DOM incorrect, script exécuté trop tôt | Console : erreurs, testez document.querySelector |
Corrigez le sélecteur, utilisez defer ou attendez DOMContentLoaded si nécessaire |
| Après modification, rien ne change | Cache navigateur/CDN/plugin | DevTools > Disable cache, test en navigation privée | Videz cache plugin/CDN, force refresh, vérifiez version ?ver= |
| Erreur console “$ is not defined” | jQuery non chargé, ou script en defer mal géré |
Console, vérifiez dépendance jquery |
Ajoutez array('jquery') et adaptez votre code jQuery |
Si ça ne marche pas
1) Vérifiez l’endroit où vous avez collé le code
- Si vous l’avez mis dans un thème parent : mauvaise idée, déplacez-le dans un thème enfant ou un plugin.
- Si vous l’avez collé dans un plugin de snippets : exportez-le vers un vrai plugin. Les snippets cassent souvent sur une simple parenthèse oubliée.
2) Activez le debug proprement (sur staging)
Sur un site de test, activez les logs WP si vous savez ce que vous faites. Référence : Debugging in WordPress.
3) Inspectez Network et Console
- Network : votre fichier est-il chargé (200) ou absent (404) ?
- Console : voyez-vous une erreur JS bloquante ?
4) Désactivez temporairement l’optimisation
Désactivez temporairement :
- minification/concat JS,
- defer/delay JS,
- optimisation CSS.
J’ai souvent vu un script parfaitement enqueued être cassé par une option “Delay all JS” trop agressive.
5) Testez sans condition
Pour isoler, commentez temporairement le bloc if (!is_page('contact')) return; et vérifiez si l’asset apparaît partout. Si oui, votre problème est la condition (slug/ID, page traduite, page builder, etc.).
Pièges et erreurs courantes
| Erreur | Cause | Solution |
|---|---|---|
Coller le code dans header.php |
On suit un vieux tutoriel, ou on “teste vite” | Utilisez wp_enqueue_scripts + un plugin/thème enfant |
| Écran blanc après ajout du code | Point-virgule manquant, accolade en trop, PHP incompatible | Vérifiez les logs, revenez en arrière via FTP, assurez PHP 8.1+ |
Utiliser le mauvais hook (init au lieu de wp_enqueue_scripts) |
Confusion entre moments d’exécution | Enqueue front : wp_enqueue_scripts. Admin : admin_enqueue_scripts |
| Le CSS est chargé mais ne s’applique pas | Spécificité CSS, ordre de chargement, CSS du builder plus fort | Chargez plus tard (priorité 20), augmentez la spécificité, évitez !important systématique |
| Le JS ne se charge que parfois | Cache, optimisation, condition trop stricte | Videz cache, testez sans condition, vérifiez le slug/ID |
| “Call to undefined function …” | Code exécuté trop tôt, ou fichier inclus au mauvais endroit | Gardez l’enqueue dans le hook, ne lancez pas de fonctions WP hors contexte |
| Copier un snippet ancien incompatible | Tutoriel pré-2020, paramètres obsolètes, mauvaises pratiques | Référez-vous à la doc officielle WP 6.9+, utilisez wp_add_inline_script |
Conseils sécurité, performance et maintenance
Sécurité
- Évitez les champs d’injection de scripts accessibles à des rôles non-admin. C’est un classique des XSS.
- Si votre JS consomme des données PHP, ne concaténez pas des chaînes “à la main”. Utilisez
wp_json_encode()(comme dans l’exemple) et échappez côté sortie quand vous générez du HTML.
Performance
- Chargez vos assets uniquement là où ils servent. C’est le gain le plus simple.
- Préférez un fichier JS dédié plutôt que 30 lignes inline dans le header : c’est mieux cacheable.
- Utilisez une version stable en production (ex.
1.0.3) si vous avez un CDN agressif.filemtime()est top en dev, mais peut multiplier les variations si vous déployez souvent.
Maintenance
- Donnez des handles clairs :
bp-custom-jsplutôt quescript1. Vous vous remercierez le jour où vous devrez “dequeuer” un asset. - Centralisez vos assets dans un plugin si vous changez souvent de thème. C’est un pattern que j’applique sur beaucoup de sites éditoriaux : le thème gère le design, le plugin gère les comportements transverses.
Ressources
- Hook
wp_enqueue_scripts(Developer Reference) wp_enqueue_script()wp_enqueue_style()wp_add_inline_script()- Debugging in WordPress (wordpress.org)
- Dépôt officiel WordPress (wordpress-develop) sur GitHub
- WordPress Core Trac (suivi des tickets)
- PHP:
filemtime()
FAQ
Est-ce que je peux mettre ce code dans functions.php ?
Oui, mais uniquement dans le functions.php d’un thème enfant. Si vous changez de thème, vous perdrez ce code. Pour un site amené à évoluer, le mini-plugin est plus robuste.
Pourquoi mon CSS se charge mais n’écrase pas celui du thème/builder ?
Souvent, c’est un mélange d’ordre de chargement et de spécificité CSS. Chargez votre CSS plus tard (priorité 20), puis ajustez vos sélecteurs. Évitez de mettre !important partout : ça rend la maintenance pénible.
Mon script a besoin de jQuery : je fais comment ?
Déclarez la dépendance array('jquery') dans wp_enqueue_script(). Ensuite, écrivez votre code jQuery correctement (en évitant de supposer que $ est global).
Pourquoi mon JS ne s’exécute pas avec defer ?
defer change le moment d’exécution. Si votre script dépend d’un autre script non defer, ou si un plugin de cache réécrit tout, vous pouvez avoir un ordre inattendu. Testez sans strategy, puis réactivez progressivement.
Puis-je ajouter du JS inline quand même ?
Oui, mais via wp_add_inline_script() (ou wp_add_inline_style() pour le CSS). Ça garde l’ordre et la traçabilité.
Comment charger un script seulement sur une page créée avec un builder ?
Le plus fiable est de cibler la page par ID/slug (is_page()). La détection “le contenu contient X” est moins fiable avec Divi/Elementor/Avada.
Pourquoi mon fichier est en 404 alors que le chemin “a l’air bon” ?
Sur beaucoup d’hébergements Linux, la casse compte : custom.js et Custom.js sont deux fichiers différents. Vérifiez aussi que le fichier est bien envoyé sur le serveur.
Mon site ne reflète pas mes changements, même avec filemtime()
Regardez côté CDN (Cloudflare, etc.) et côté plugin de cache. Testez en navigation privée et cochez “Disable cache” dans DevTools. Videz ensuite le cache serveur/CDN.
Est-ce que ça marche avec un thème bloc (FSE) ?
Oui. wp_enqueue_scripts reste valable. Pour des styles purement “design system”, theme.json est souvent plus adapté, mais ça ne remplace pas le chargement de JS.
Je peux charger un script externe (CDN) avec wp_enqueue_script ?
Oui : mettez l’URL complète en $src. Vérifiez la politique de confidentialité/consentement si c’est un script de tracking, et testez les blocages (adblockers, CSP).