
🛠 Korrekte JavaScript-Einbindung in WordPress-Themes
Ihr WordPress-Galerie funktioniert nach einem Update nicht mehr. Kommt Ihnen das bekannt vor?
Fast immer ist die Ursache JavaScript, das direkt in der header.php eingebunden wird, ohne Hooks, ohne Abhängigkeiten, ohne zu berücksichtigen, dass ein Caching-Plugin die Ladereihenfolge durcheinanderbringen kann. Ein Plugin zieht jQuery herein, ein anderes seine eigene jQuery-Version, und Ihr Skript landet dazwischen und stürzt mit $ is not defined ab.
In der Praxis genügt ein einziger wp_enqueue_script-Aufruf an der richtigen Stelle, um Konflikte für immer zu vergessen. Nachfolgend eine vollständige Aufschlüsselung: von Anfängerfehlern über defer/async-Strategien bis hin zu Feinjustierungsoptionen, die mit WordPress 6.6 hinzugekommen sind.
💡 Kurzüberblick:
- Fügen Sie keine Script-Tags direkt in header.php oder footer.php ein: Das erzeugt Konflikte mit Plugins und zerstört Child-Themes
- Binden Sie JavaScript über wp_enqueue_script in der functions.php mit dem wp_enqueue_scripts-Hook ein: WordPress platziert die Tags selbstständig im Head oder vor /body
- Für kurzen Inline-Code nutzen Sie wp_add_inline_script, nicht ein nacktes Script-Tag: Das bewahrt die Ausführungsreihenfolge und gibt Plugins die Möglichkeit, den Code abzufangen
- Geben Sie ab WordPress 6.3 eine defer- oder async-Strategie direkt in den Aufrufparametern an, und ab 6.6 zusätzlich fetchpriority
- Entfernen Sie fremde Skripte per wp_dequeue_script, wenn ein Plugin Ihre Seite ausbremst: Die Hook-Priorität entscheidet
Wie JavaScript falsch in WordPress eingebunden wird
Typisches Szenario: Sie müssen Ihre custom.js laden, und der Entwickler fügt diese Zeile in die header.php ein:
1 <script src="<?php echo get_template_directory_uri(); ?>/js/custom.js"></script>
Scheint zu funktionieren. Aber dieser Ansatz erzeugt drei Probleme.
Konflikte mit Plugins. Ein Caching-Plugin kombiniert Skripte in anderer Reihenfolge, ein Minification-Plugin benennt die Datei um und zerstört den Pfad. Wenn ein anderes Plugin jQuery bereits geladen hat und Sie es erneut laden, kommt es zu doppelter Ladung und Konsolenfehlern.
Kein Überschreiben per Child-Theme möglich. Bei Verwendung eines Child-Themes wird die header.php selten kopiert. Ist das Skript in der header.php des Eltern-Themes hartcodiert, kann das Child-Theme es nicht entfernen oder ersetzen, ohne die gesamte Datei zu kopieren, und das bedeutet, dass Änderungen beim Update des Eltern-Themes verloren gehen.
Keine Abhängigkeiten. Der Browser lädt Ihr Skript vor jQuery, und Sie erhalten $ is not defined. Das Skript wird auf allen Seiten geladen, auch dort, wo es nicht benötigt wird, und zusätzliche Requests bremsen die Seite aus.
Der richtige Weg: wp_enqueue_script
WordPress stellt ein Warteschlangensystem für Skripte und Styles bereit. Sie fügen <script> nicht manuell ein, sondern registrieren das Skript über PHP, geben Abhängigkeiten und den Ladeort an. WordPress platziert die Tags selbstständig in <head> oder vor </body>.
Minimales funktionierendes Beispiel für die functions.php Ihres Themes:
1 /** 2 * Enqueue the main theme script. 3 */ 4 function 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 } 13 add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_scripts' );
Die Funktion wp_enqueue_script akzeptiert fünf Parameter. $handle, eine eindeutige Kennung: Hat ein anderes Plugin bereits ein Skript mit demselben Handle registriert, kommt es zu keiner doppelten Ladung. $deps, ein Array mit Handle-Abhängigkeiten: WordPress lädt die benötigten Skripte vor Ihrem. $in_footer mit dem Wert true platziert den <script>-Tag vor </body>, was das Rendern der Seite beschleunigt.
Hinweis: get_template_directory_uri() zeigt auf den Ordner des Eltern-Themes. Verwenden Sie in einem Child-Theme get_stylesheet_directory_uri(), dann zeigt die URL auf den Child-Ordner, und Ihr Skript geht bei einem Update des Eltern-Themes nicht verloren.
Ladestrategien: defer, async und fetchpriority
Ab WordPress 6.3 akzeptiert der Parameter $args ein Array mit zusätzlichen Einstellungen:
1 wp_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 );
Die defer-Strategie sagt dem Browser: „Lade das Skript parallel, führe es nach dem DOM-Aufbau aus." Die Ausführungsreihenfolge ist garantiert, Skripte mit defer werden in der Reihenfolge ausgeführt, in der sie zum DOM hinzugefügt wurden. Die async-Strategie bedeutet „Führe aus, sobald geladen", die Reihenfolge ist nicht garantiert. Für Theme-Skripte, die vom DOM abhängen, wählen Sie defer.
Ab WordPress 6.6 hat das $args-Array zwei weitere Parameter erhalten. fetchpriority steuert die Ladepriorität ('high' oder 'low'), nützlich für kritische Skripte, die vor anderen laden sollen. module_dependencies akzeptiert ein Array mit Modul-IDs für dynamischen Import, das ist für fortgeschrittene Szenarien mit ES-Modulen. Wichtig: Wenn Sie module_dependencies angeben, muss das Skript im Footer laden (in_footer => true) oder mit der defer-Strategie, sonst ist die Modul-Import-Map nicht bereit, wenn das Skript ausgeführt wird.
Welche Skripte bereits in WordPress enthalten sind
WordPress registriert standardmäßig Dutzende JavaScript-Bibliotheken: jQuery, jQuery UI, Backbone, wp-api, MediaElement.js und andere. Vollständige Liste in der offiziellen Dokumentation.
Die wichtigste Regel: Laden Sie jQuery niemals von einem CDN wie Google oder cdnjs, wenn Ihr Theme im WordPress-Ökosystem arbeitet. WordPress selbst stellt jQuery unter dem Handle jquery bereit. Um es zu nutzen, geben Sie einfach array( 'jquery' ) in den Abhängigkeiten an, WordPress lädt dann seine eigene, auf Kompatibilität mit dem gesamten Core getestete Version.
Sie können prüfen, ob eine Bibliothek registriert ist, mit wp_script_is():
1 if ( wp_script_is( 'jquery-ui-datepicker', 'registered' ) ) { 2 // Library is available — just add to $deps 3 }
Verwendung des wp_enqueue_scripts-Hooks
Der wp_enqueue_scripts-Hook wird im Frontend ausgelöst. Darin werden die wp_enqueue_script-Aufrufe eingebettet. Rufen Sie die Funktion nicht direkt im Rumpf der functions.php ohne Hook auf, das Skript könnte laden, bevor WordPress Systembibliotheken registriert.
Für den Admin-Bereich verwenden Sie einen separaten Hook:
1 add_action( 'admin_enqueue_scripts', 'mytheme_admin_scripts' ); 2 function 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 }
Konditionales Laden spart Ressourcen: Ein Skript für eine Optionsseite sollte nicht auf allen Admin-Seiten laden. Der Parameter $hook_suffix wird von WordPress automatisch übergeben, nutzen Sie ihn.
Wird ein Skript sowohl im Frontend als auch im Admin benötigt, hängen Sie eine Funktion an beide Hooks:
1 add_action( 'wp_enqueue_scripts', 'mytheme_global_scripts' ); 2 add_action( 'admin_enqueue_scripts', 'mytheme_global_scripts' );
Inline-JavaScript hinzufügen: wp_add_inline_script
Nicht jeder Code gehört in eine separate Datei. Für kurze Snippets, Zähler, Konfigurationsvariablen, schnelle Handler stellt WordPress wp_add_inline_script bereit:
1 function 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 } 9 add_action( 'wp_enqueue_scripts', 'mytheme_inline_config' );
Der dritte Parameter, 'before' oder 'after', bestimmt, wo der Code relativ zum angegebenen Skript eingefügt wird. Das ist praktisch, um PHP-Variablen an JavaScript zu übergeben: die AJAX-Handler-URL, den Security-Nonce-Key, die aktuelle Beitrags-ID.
Wichtiges Detail: wp_add_inline_script funktioniert nur mit einem registrierten Skript. Übergeben Sie ein Handle, das sich nicht in der Warteschlange befindet, wird der Code nicht ausgegeben. Also zuerst wp_enqueue_script, dann wp_add_inline_script.
Alternative für Child-Themes: wp_head und wp_footer
Wenn Sie in einem Child-Theme arbeiten und keine separate Datei anlegen möchten, können Sie Code direkt über die Hooks wp_head (in <head>) oder wp_footer (vor </body>) ausgeben:
1 add_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 } );
Diese Methode ist kürzer, aber weniger flexibel als wp_enqueue_script: keine Abhängigkeiten, keine Versionierung und keine Möglichkeit, das Skript per Child-Theme zu entfernen. Nutzen Sie sie für kleine Korrekturen, wenn Sie keine separate Datei anlegen möchten.
Wie man ein von einem Plugin oder Theme hinzugefügtes Skript entfernt
Manchmal lädt ein Plugin ein unnötiges Skript auf allen Seiten und bremst die Seite aus. Sie können es mit wp_dequeue_script entfernen:
1 function mytheme_dequeue_plugin_scripts() { 2 if ( ! is_page( 'contacts' ) ) { 3 wp_dequeue_script( 'plugin-handle' ); 4 } 5 } 6 add_action( 'wp_enqueue_scripts', 'mytheme_dequeue_plugin_scripts', 20 );
Die Priorität 20 (drittes Argument von add_action) platziert Ihre Funktion nach der Plugin-Registrierung, sonst ist das Handle noch nicht in der Warteschlange. Das Handle eines Skripts finden Sie über die Browser-Konsole: Öffnen Sie den Seitenquelltext und suchen Sie das id-Attribut am <script>-Tag, das Handle entspricht in der Regel der id ohne das Suffix -js.
Wenn Sie ein Skript vollständig ersetzen müssen, deregistrieren Sie zuerst das alte per wp_deregister_script und registrieren dann das neue:
1 function 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 } 5 add_action( 'wp_enqueue_scripts', 'mytheme_replace_script', 20 );
Erstellen Sie vor solchen Eingriffen ein vollständiges Backup der Seite. Das Ersetzen von Plugin-Skripten ist ein direkter Weg zu kaputter Funktionalität, wenn Sie nicht in einer Staging-Umgebung testen.
Das Video oben zeigt eine schrittweise Aufschlüsselung des Einbindens von CSS und JavaScript in einem WordPress-Theme mittels wp_enqueue_script und wp_enqueue_style. Wenn Sie neu im Umgang mit Hooks sind, beginnen Sie damit und kehren Sie dann für Details zu diesem schriftlichen Leitfaden zurück.
⁉️🤔 Häufig gestellte Fragen
Ist es zwingend, wp_enqueue_script für jede js-Datei zu verwenden?
In der Praxis ja, für alle global geladenen Skripte. Für ein Skript, das nur auf einer einzigen Seite funktioniert und dynamisch generiert wird, ist es akzeptabel,
<script>direkt im Template einzufügen. Sobald Sie jedoch zwei oder mehr Skripte haben, spart die Warteschlange überwp_enqueue_scriptStunden an Fehlersuche.
Wie unterscheidet sich wp_register_script von wp_enqueue_script?
wp_register_scriptregistriert ein Skript lediglich im System (setzt Handle, Pfad, Abhängigkeiten), gibt aber den Tag nicht auf der Seite aus.wp_enqueue_scriptregistriert UND stellt es sofort zur Ausgabe in die Warteschlange. Die Trennung ist nützlich, wenn das Skript nicht immer benötigt wird: Einmal in derfunctions.phpregistrieren undwp_enqueue_script('my-handle')nur auf den erforderlichen Seiten aufrufen.
Kann ich Skripte von einem externen CDN laden?
Technisch ja, übergeben Sie die vollständige URL als zweiten Parameter. Für jQuery und andere Core-Bibliotheken von WordPress ist das jedoch schlechte Praxis: WordPress enthält sie bereits und testet die Kompatibilität. Ein externes CDN ist für Drittanbieterdienste wie Google Analytics, reCAPTCHA, Chat-Widgets gerechtfertigt. Geben Sie dort die URL unverändert an.
Wie überprüfe ich, ob ein Skript tatsächlich geladen wurde?
Öffnen Sie die Entwicklertools (F12), Tab Netzwerk, filtern Sie nach JS und laden Sie die Seite neu. Ihre Datei sollte mit Statuscode 200 in der Liste erscheinen. Fehlt das Skript, prüfen Sie, ob der
wp_enqueue_scripts-Hook auf dieser Seite ausgelöst wird und ob der Dateipfad korrekt ist. Geben Sie zum Debuggenget_template_directory_uri()separat aus und vergleichen Sie die URL.
Was tun, wenn Skripte nach einem Theme-Update nicht mehr funktionieren?
Höchstwahrscheinlich hat das Update Ihre
functions.phpüberschrieben. Die Lösung ist ein Child-Theme: Erstellen Sie eines, verschieben Sie Ihre Funktionen dorthin und aktivieren Sie es. Danach lassen Updates des Eltern-Themes Ihren Code unangetastet.
Was bedeutet der Fehler „$ is not defined" bei der Verwendung von jQuery?
WordPress lädt jQuery im noConflict-Modus, die Variable
$wird nicht von jQuery belegt, um Konflikte mit anderen Bibliotheken zu vermeiden. Verwenden Sie den vollständigen NamenjQueryanstelle von$oder verpacken Sie den Code in eine selbstaufrufende Funktion:(function($) { ... })(jQuery);.
Lohnt sich der Aufwand mit wp_enqueue_script für ein paar Skripte?
Wenn Sie mehr als ein Plugin auf der Seite haben, lohnt es sich. Die Skript-Warteschlange von WordPress ist so konzipiert, dass ein einziges Plugin, das jQuery direkt lädt, die halbe Seite lahmlegt, sobald Sie ein Caching-Plugin installieren. wp_enqueue_script beseitigt diese gesamte Problemklasse.
Für ein Theme mit fünf Dateien nutzen Sie wp_enqueue_script. Für ein kurzes Snippet auf einer bestimmten Seite genügen wp_add_inline_script oder der wp_footer-Hook. Aber sobald Sie zwei oder mehr Skripte haben, kehren Sie zur Warteschlange zurück. Eine Stunde, die Sie jetzt in korrektes Enqueuing investieren, spart Ihnen einen Abend Fehlersuche nach dem nächsten WordPress-Update.



