Skip to content

Allt om WordPress, webbutveckling — och mer därtill

🛠 Proper javascript inclusion in WordPress themes

🛠 Proper javascript inclusion in WordPress themes

Din WordPress-galleri slutade fungera efter en uppdatering. Låter det bekant?

Nästan alltid är orsaken JavaScript som länkas direkt i header.php, utan hooks, utan beroenden, utan hänsyn till att ett caching-plugin kan kasta om laddningsordningen. Ett plugin drar in jQuery, ett annat drar in sin egen version av jQuery, och ditt skript hamnar mellan dem och kraschar med $ is not defined.

I praktiken räcker ett enda wp_enqueue_script-anrop på rätt ställe för att glömma konflikter för alltid. Nedan följer en komplett genomgång: från nybörjarmisstag till strategier för defer/async och finjusteringsmöjligheter som dök upp i WordPress 6.6.

💡 Snabb översikt:

  • Stoppa inte in script-taggar direkt i header.php eller footer.php: det skapar konflikter med plugins och förstör child themes
  • Köa JavaScript via wp_enqueue_script i functions.php med wp_enqueue_scripts-hooken: WordPress placerar själv taggarna i head eller före /body
  • För kort inline-kod använd wp_add_inline_script, inte en ren script-tagg: bevarar exekveringsordningen och ger plugins en chans att fånga upp koden
  • På WordPress 6.3+ ange en defer- eller async-strategi direkt i anropsparametrarna, och från och med 6.6 även fetchpriority
  • Avköa tredjepartsskript via wp_dequeue_script om ett plugin saktar ner din sajt: hook-prioritet avgör

Hur JavaScript läggs till på fel sätt i WordPress

Typiskt scenario: du behöver ladda din custom.js, och utvecklaren stoppar in den här raden i header.php:

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

Verkar fungera. Men det här tillvägagångssättet skapar tre problem.

Konflikter med plugins. Ett caching-plugin slår ihop skript i en annan ordning, ett minifieringsplugin byter namn på filen och bryter sökvägen. Om ett annat plugin redan laddat jQuery och du laddar det igen uppstår dubbelladdning och konsolfel.

Kan inte åsidosättas via ett child theme. När man använder ett child theme kopieras sällan header.php. Om skriptet är hårdkodat i föräldratemats header.php kan child theme't inte avköa eller ersätta det utan att kopiera hela filen, och det innebär att ändringar försvinner när föräldratemat uppdateras.

Inga beroenden. Webbläsaren laddar ditt skript före jQuery, och du får $ is not defined. Skriptet laddas på alla sidor, även där det inte behövs, och extra anrop saktar ner sajten.

Rätt sätt: wp_enqueue_script

WordPress tillhandahåller ett kösystem för skript och stilmallar. Du stoppar inte in <script> manuellt, istället registrerar du skriptet via PHP, anger beroenden och laddningsplats. WordPress placerar taggarna i <head> eller före </body> själv.

Minimalt fungerande exempel för ditt temas functions.php:

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

Funktionen wp_enqueue_script tar emot fem parametrar. $handle, en unik identifierare: om ett annat plugin redan registrerat ett skript med samma handle blir det ingen dubblettladdning. $deps, en array med handle-beroenden: WordPress laddar de nödvändiga skripten före ditt. $in_footer med värdet true placerar <script>-taggen före </body>, vilket snabbar upp sidrenderingen.

Notera: get_template_directory_uri() pekar på föräldratemats mapp. I ett child theme använd get_stylesheet_directory_uri(), URL:en pekar då på child-mappen, och ditt skript försvinner inte när föräldratemat uppdateras.

Laddningsstrategier: defer, async och fetchpriority

Från och med WordPress 6.3 accepterar parametern $args en array med ytterligare inställningar:

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

Strategin defer säger till webbläsaren: "ladda skriptet parallellt, kör efter DOM-uppbyggnad". Exekveringsordningen garanteras, skript med defer körs i den ordning de lades till i DOM:en. Strategin async betyder "kör så snart det är laddat", ordningen garanteras inte. För temaskript som är beroende av DOM:en, välj defer.

Från och med WordPress 6.6 fick arrayen $args ytterligare två parametrar. fetchpriority styr laddningsprioritet ('high' eller 'low'), användbart för kritiska skript som ska laddas före andra. module_dependencies tar emot en array med modul-ID:n för dynamisk import, detta är för avancerade scenarier med ES-moduler. Viktigt: när man anger module_dependencies måste skriptet laddas i sidfoten (in_footer => true) eller med strategin defer, annars är modulimportkartan inte redo när skriptet körs.

Vilka skript som redan finns i WordPress

WordPress registrerar dussintals JavaScript-bibliotek direkt ur lådan: jQuery, jQuery UI, Backbone, wp-api, MediaElement.js med flera. Fullständig lista i den officiella dokumentationen.

Huvudregeln: ladda aldrig jQuery från ett CDN som Google eller cdnjs om ditt tema fungerar i WordPress-ekosystemet. WordPress tillhandahåller själv jQuery med handtaget jquery. För att använda det, ange helt enkelt array( 'jquery' ) i beroenden, så laddar WordPress sin egen version som är testad för kompatibilitet med hela kärnan.

Du kan kontrollera om ett bibliotek är registrerat via wp_script_is():

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

Använda wp_enqueue_scripts-hooken

Hooken wp_enqueue_scripts körs på frontend. Det är denna som wp_enqueue_script-anrop lindas in i. Anropa inte funktionen direkt i brödtexten i functions.php utan en hook, skriptet kan laddas innan WordPress registrerar systembiblioteken.

För adminområdet använd en separat hook:

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}

Villkorlig laddning sparar resurser: ett skript för en inställningssida ska inte laddas på alla adminsidor. Parametern $hook_suffix skickas automatiskt av WordPress, använd den.

Om ett skript behövs både på frontend och i admin, hooka en funktion till båda:

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

Lägga till inline JavaScript: wp_add_inline_script

All kod är inte värd att lägga i en separat fil. För korta snuttar, räknare, konfigurationsvariabler, snabba hanterare tillhandahåller WordPress 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' );

Den tredje parametern, 'before' eller 'after', avgör var koden infogas i förhållande till det angivna skriptet. Detta är praktiskt för att skicka PHP-variabler till JavaScript: URL:en för AJAX-hanteraren, security nonce-nyckeln, aktuellt post-ID.

Viktig detalj: wp_add_inline_script fungerar bara med ett registrerat skript. Om du skickar en handle som inte finns i kön kommer koden inte att matas ut. Så först wp_enqueue_script, sedan wp_add_inline_script.

Alternativ för child themes: wp_head och wp_footer

Om du arbetar i ett child theme och inte vill skapa en separat fil kan du mata ut kod direkt via hookarna wp_head (i <head>) eller wp_footer (före </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 } );

Denna metod är kortare men mindre flexibel än wp_enqueue_script: inga beroenden, versionshantering eller möjlighet att avköa skriptet via ett child theme. Använd den för små fixar när du inte vill skapa en separat fil.

Hur man avköar ett skript som lagts till av ett plugin eller tema

Ibland laddar ett plugin ett onödigt skript på alla sidor och saktar ner sajten. Du kan ta bort det 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 );

Prioritet 20 (tredje argumentet i add_action) placerar din funktion efter plugin-registreringen, annars finns inte handtaget i kön ännu. Du kan hitta ett skripts handle via webbläsarkonsolen: öppna sidkällan och leta reda på id-attributet på <script>-taggen, handtaget matchar vanligtvis id utan suffixet -js.

Om du behöver ersätta ett skript helt, avregistrera först det gamla via wp_deregister_script, registrera sedan det nya:

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

Gör en fullständig säkerhetskopia av sajten före sådana operationer. Att ersätta plugin-skript är en direkt väg till trasig funktionalitet om du inte testar i en staging-miljö.

Videon ovan visar en steg-för-steg-genomgång av hur man köar CSS och JavaScript i ett WordPress-tema via wp_enqueue_script och wp_enqueue_style. Om du är ny på hooks, börja med den och återvänd sedan till denna skrivna guide för detaljer.

⁉️🤔 Vanliga frågor

Är det obligatoriskt att använda wp_enqueue_script för varje js-fil?

I praktiken, ja, för alla globalt laddade skript. För ett skript som bara fungerar på en enda sida och genereras dynamiskt är det acceptabelt att infoga <script> direkt i mallen. Men så snart du har två eller fler skript sparar kön via wp_enqueue_script timmar av felsökning.

Hur skiljer sig wp_register_script från wp_enqueue_script?

wp_register_script registrerar bara ett skript i systemet (sätter handle, sökväg, beroenden) men matar inte ut taggen på sidan. wp_enqueue_script registrerar OCH köar omedelbart för utmatning. Separationen är användbar när skriptet inte alltid behövs: registrera en gång i functions.php, och anropa wp_enqueue_script('my-handle') endast på de sidor som krävs.

Kan jag ladda skript från ett externt CDN?

Tekniskt sett, ja, skicka den fullständiga URL:en som den andra parametern. Men för jQuery och andra centrala WordPress-bibliotek är detta dålig praxis: WordPress inkluderar dem redan och testar kompatibilitet. Ett externt CDN är motiverat för tredjepartstjänster som Google Analytics, reCAPTCHA, chattwidgetar. Ange där URL:en som den är.

Hur kontrollerar jag att ett skript faktiskt laddades?

Öppna utvecklarverktygen (F12), fliken Nätverk, filtrera på JS och uppdatera sidan. Din fil ska finnas i listan med statuskod 200. Om skriptet saknas, kontrollera att hooken wp_enqueue_scripts körs på denna sida och att filsökvägen är korrekt. För felsökning, mata ut get_template_directory_uri() separat och jämför URL:en.

Vad ska jag göra om skript slutar fungera efter en temauppdatering?

Troligtvis skrev uppdateringen över din functions.php. Lösningen är ett child theme: skapa ett, flytta dina funktioner dit och aktivera det. Efter det lämnar uppdateringar av föräldratemat din kod intakt.

Vad betyder felet "$ is not defined" när man använder jQuery?

WordPress laddar jQuery i noConflict-läge, variabeln $ upptas inte av jQuery för att undvika konflikter med andra bibliotek. Använd det fullständiga namnet jQuery istället för $ eller linda in koden i en självanropande funktion: (function($) { ... })(jQuery);.

Är det värt besväret med wp_enqueue_script för ett par skript?

Om du har mer än ett plugin på sajten är det värt det. WordPress skriptkö är utformad så att ett plugin som laddar jQuery direkt förstör halva sajten i samma stund som du installerar ett caching-plugin. wp_enqueue_script eliminerar hela denna problemklass.

För ett tema med fem filer, använd wp_enqueue_script. För en kort snutt på en specifik sida duger wp_add_inline_script eller hooken wp_footer. Men så snart du har två eller fler skript, återgå till kön. En timme som läggs på korrekt köhantering nu sparar en kvälls felsökning efter nästa WordPress-uppdatering.