Skip to content

Tutto per WordPress, lo sviluppo web — e non solo

🛠 Inclusione corretta di JavaScript nei temi WordPress

🛠 Inclusione corretta di JavaScript nei temi WordPress

Il tuo WordPress ha smesso di funzionare dopo un aggiornamento. Ti suona familiare?

Quasi sempre la causa è JavaScript collegato direttamente in header.php, senza hook, senza dipendenze, senza considerare che un plugin di caching può alterare l'ordine di caricamento. Un plugin carica jQuery, un altro carica la propria versione di jQuery e il tuo script finisce in mezzo e si blocca con $ is not defined.

In pratica, una singola chiamata wp_enqueue_script nel posto giusto basta per dimenticare i conflitti per sempre. Di seguito trovi un'analisi completa: dagli errori da principiante alle strategie defer/async e alle opzioni di ottimizzazione introdotte in WordPress 6.6.

💡 Panoramica rapida:

  • Non inserire i tag script direttamente in header.php o footer.php: crea conflitti con i plugin e rompe i temi child
  • Registra JavaScript tramite wp_enqueue_script in functions.php con l'hook wp_enqueue_scripts: WordPress inserirà i tag nell'head o prima di /body da solo
  • Per brevi porzioni di codice inline usa wp_add_inline_script, non un tag script nudo: preserva l'ordine di esecuzione e dà ai plugin la possibilità di intercettare il codice
  • Su WordPress 6.3+ specifica una strategia defer o async direttamente nei parametri della chiamata e, a partire dalla 6.6, anche fetchpriority
  • Rimuovi script di terze parti con wp_dequeue_script se un plugin rallenta il sito: la priorità dell'hook è decisiva

Come si aggiunge JavaScript in WordPress in modo scorretto

Scenario tipico: devi caricare il tuo custom.js e lo sviluppatore inserisce questa riga in header.php:

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

Sembra funzionare. Ma questo approccio crea tre problemi.

Conflitti con i plugin. Un plugin di caching combina gli script in un ordine diverso, un plugin di minificazione rinomina il file e rompe il percorso. Se un altro plugin ha già caricato jQuery e tu lo carichi di nuovo, si verificano doppio caricamento ed errori nella console.

Impossibilità di override tramite tema child. Quando si usa un tema child, header.php viene copiato raramente. Se lo script è scritto direttamente nel header.php del tema parent, il tema child non può rimuoverlo o sostituirlo senza copiare l'intero file e questo significa che le modifiche andranno perse all'aggiornamento del tema parent.

Nessuna dipendenza. Il browser carica il tuo script prima di jQuery e ottieni $ is not defined. Lo script si carica su tutte le pagine, anche dove non serve, e le richieste extra rallentano il sito.

Il modo corretto: wp_enqueue_script

WordPress mette a disposizione un sistema di accodamento per script e stili. Non inserisci <script> manualmente, ma registri lo script tramite PHP, specifichi le dipendenze e la posizione di caricamento. WordPress inserisce i tag in <head> o prima di </body> da solo.

Esempio minimo funzionante per il functions.php del tuo tema:

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 funzione wp_enqueue_script accetta cinque parametri. $handle, un identificatore univoco: se un altro plugin ha già registrato uno script con lo stesso handle, non ci sarà un doppio caricamento. $deps, un array di handle delle dipendenze: WordPress caricherà gli script richiesti prima del tuo. $in_footer con valore true posiziona il tag <script> prima di </body>, accelerando il rendering della pagina.

Nota: get_template_directory_uri() punta alla cartella del tema parent. In un tema child usa get_stylesheet_directory_uri(), l'URL punterà alla cartella child e il tuo script non andrà perso all'aggiornamento del tema parent.

Strategie di caricamento: defer, async e fetchpriority

A partire da WordPress 6.3, il parametro $args accetta un array con impostazioni aggiuntive:

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 strategia defer dice al browser: "carica lo script in parallelo, eseguilo dopo la costruzione del DOM". L'ordine di esecuzione è garantito, gli script con defer vengono eseguiti nell'ordine in cui sono stati aggiunti al DOM. La strategia async significa "esegui appena caricato", l'ordine non è garantito. Per gli script del tema che dipendono dal DOM, scegli defer.

A partire da WordPress 6.6, l'array $args ha guadagnato altri due parametri. fetchpriority controlla la priorità di caricamento ('high' o 'low'), utile per gli script critici che devono caricarsi prima di altri. module_dependencies accetta un array di ID modulo per l'import dinamico, per scenari avanzati con moduli ES. Importante: quando si specifica module_dependencies lo script deve caricarsi nel footer (in_footer => true) o con la strategia defer, altrimenti la mappa di import dei moduli non sarà pronta quando lo script viene eseguito.

Quali script sono già presenti in WordPress

WordPress registra decine di librerie JavaScript di default: jQuery, jQuery UI, Backbone, wp-api, MediaElement.js e altre. Elenco completo nella documentazione ufficiale.

La regola principale: non caricare mai jQuery da un CDN come Google o cdnjs se il tuo tema funziona nell'ecosistema WordPress. WordPress stesso fornisce jQuery con l'handle jquery. Per usarlo, basta specificare array( 'jquery' ) nelle dipendenze, WordPress caricherà la propria versione testata per la compatibilità con l'intero core.

Puoi verificare se una libreria è registrata con wp_script_is():

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

Usare l'hook wp_enqueue_scripts

L'hook wp_enqueue_scripts si attiva sul frontend. È all'interno di questo hook che si inseriscono le chiamate wp_enqueue_script. Non chiamare la funzione direttamente nel corpo di functions.php senza un hook, lo script potrebbe caricarsi prima che WordPress registri le librerie di sistema.

Per l'area di amministrazione usa un hook separato:

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}

Il caricamento condizionale fa risparmiare risorse: uno script per una pagina delle opzioni non deve caricarsi su tutte le pagine admin. Il parametro $hook_suffix viene passato automaticamente da WordPress, usalo.

Se uno script serve sia nel frontend che in admin, aggancia una funzione a entrambi:

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

Aggiungere JavaScript inline: wp_add_inline_script

Non tutto il codice vale la pena di essere messo in un file separato. Per brevi snippet, contatori, variabili di configurazione, handler rapidi, WordPress mette a disposizione 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' );

Il terzo parametro, 'before' o 'after', determina dove viene inserito il codice rispetto allo script specificato. È comodo per passare variabili PHP a JavaScript: l'URL del gestore AJAX, la chiave nonce di sicurezza, l'ID del post corrente.

Dettaglio importante: wp_add_inline_script funziona solo con uno script registrato. Se passi un handle che non è in coda, il codice non verrà emesso. Quindi prima wp_enqueue_script, poi wp_add_inline_script.

Alternativa per temi child: wp_head e wp_footer

Se lavori in un tema child e non vuoi creare un file separato, puoi emettere codice direttamente tramite gli hook wp_head (in <head>) o wp_footer (prima di </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 } );

Questo metodo è più breve ma meno flessibile di wp_enqueue_script: niente dipendenze, versionamento o possibilità di rimuovere lo script tramite un tema child. Usalo per piccole correzioni quando non vuoi creare un file separato.

Come rimuovere uno script aggiunto da un plugin o tema

A volte un plugin carica uno script non necessario su tutte le pagine e rallenta il sito. Puoi rimuoverlo con 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 (terzo argomento di add_action) posiziona la tua funzione dopo la registrazione del plugin, altrimenti l'handle non sarà ancora in coda. Puoi trovare l'handle di uno script tramite la console del browser: apri il sorgente della pagina e cerca l'attributo id sul tag <script>, di solito l'handle corrisponde all'id senza il suffisso -js.

Se devi sostituire completamente uno script, prima deregistra quello vecchio con wp_deregister_script, poi registra quello nuovo:

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 );

Prima di operazioni del genere fai un backup completo del sito. Sostituire gli script dei plugin è la via diretta per rompere funzionalità se non fai i test in un ambiente di staging.

Il video qui sopra mostra un'analisi passo passo dell'accodamento di CSS e JavaScript in un tema WordPress tramite wp_enqueue_script e wp_enqueue_style. Se sei nuovo agli hook, inizia da lì, poi torna a questa guida scritta per i dettagli.

⁉️🤔 Domande frequenti

È obbligatorio usare wp_enqueue_script per ogni file js?

In pratica sì, per tutti gli script caricati globalmente. Per uno script che funziona su una singola pagina ed è generato dinamicamente, è accettabile inserire <script> direttamente nel template. Ma appena hai due o più script, l'accodamento tramite wp_enqueue_script fa risparmiare ore di debugging.

In cosa wp_register_script differisce da wp_enqueue_script?

wp_register_script si limita a registrare uno script nel sistema (imposta handle, percorso, dipendenze) ma non emette il tag nella pagina. wp_enqueue_script registra E mette immediatamente in coda per l'output. La separazione è utile quando lo script non serve sempre: registralo una volta in functions.php e chiama wp_enqueue_script('my-handle') solo nelle pagine richieste.

Posso caricare script da un CDN esterno?

Tecnicamente sì, passa l'URL completo come secondo parametro. Ma per jQuery e altre librerie core di WordPress è una cattiva pratica: WordPress le include già e ne testa la compatibilità. Un CDN esterno è giustificato per servizi di terze parti come Google Analytics, reCAPTCHA, widget di chat. In quel caso specifica l'URL così com'è.

Come verifico che uno script sia stato effettivamente caricato?

Apri gli strumenti per sviluppatori (F12), scheda Network, filtra per JS e ricarica la pagina. Il tuo file dovrebbe comparire nell'elenco con codice di stato 200. Se lo script manca, verifica che l'hook wp_enqueue_scripts si attivi su quella pagina e che il percorso del file sia corretto. Per il debug, stampa get_template_directory_uri() separatamente e confronta l'URL.

Cosa fare se gli script smettono di funzionare dopo un aggiornamento del tema?

Molto probabilmente l'aggiornamento ha sovrascritto il tuo functions.php. La soluzione è un tema child: creane uno, sposta lì le tue funzioni e attivalo. Dopodiché, gli aggiornamenti del tema parent lasceranno intatto il tuo codice.

Cosa significa l'errore "$ is not defined" quando si usa jQuery?

WordPress carica jQuery in modalità noConflict, la variabile $ non è occupata da jQuery per evitare conflitti con altre librerie. Usa il nome completo jQuery al posto di $ oppure avvolgi il codice in una funzione auto-invocante: (function($) { ... })(jQuery);.

Vale la pena preoccuparsi di wp_enqueue_script per un paio di script?

Se hai più di un plugin sul sito, ne vale la pena. La coda degli script di WordPress è progettata in modo che un plugin che carica jQuery direttamente rompa metà del sito nel momento in cui installi un plugin di caching. wp_enqueue_script elimina questa intera classe di problemi.

Per un tema di cinque file, usa wp_enqueue_script. Per un breve snippet su una pagina specifica, wp_add_inline_script o l'hook wp_footer andranno bene. Ma appena hai due o più script, torna alla coda. Un'ora spesa per un corretto accodamento ora ti risparmia una serata di debugging dopo il prossimo aggiornamento di WordPress.