Manuel Killert
Ratgeber · WordPress · Three.js

Three.js in WordPress einbinden.

WordPress und Three.js vertragen sich gut — wenn man ein paar Dinge beachtet. Hier sind drei Wege, eine 3D-Szene sauber einzubinden, mit Code und den Fallstricken, die bei WordPress besonders häufig sind.

Live-Demos ansehen →Projekt anfragen
Kurz gesagt

Das Skript gehört nicht in einen HTML-Block und nicht global in das Theme. Sauber ist es, Three.js über wp_enqueue_script als ES-Modul nur auf den Seiten zu laden, die die Szene zeigen — per Seitenvorlage, Shortcode oder eigenem Block.

Warum nicht einfach in einen HTML-Block?

Technisch geht es. Aber Page-Builder und Editor verändern eingefügtes JavaScript gern, Module werden falsch geladen, und bei jedem Update droht der Code zu verschwinden. Außerdem lädt das Skript dann oft auf jeder Seite, auch dort, wo kein 3D zu sehen ist — und kostet überall Ladezeit.

Weg 1: Shortcode im Child-Theme.

Der pragmatischste Weg für eine oder wenige Szenen. Der Code liegt im Child-Theme und übersteht Theme-Updates.

functions.php (Child-Theme)
<?php
// Shortcode [szene_3d] rendert den Container
add_shortcode('szene_3d', function () {
    // Skript nur laden, wenn der Shortcode wirklich auf der Seite steht
    wp_enqueue_script('szene-3d');
    return '<div id="szene-3d" style="width:100%;height:520px"></div>';
});

add_action('wp_enqueue_scripts', function () {
    wp_register_script(
        'szene-3d',
        get_stylesheet_directory_uri() . '/js/szene.js',
        [],
        '1.0',
        ['in_footer' => true, 'strategy' => 'defer']
    );
});

// Als ES-Modul ausliefern, damit import funktioniert
add_filter('script_loader_tag', function ($tag, $handle) {
    if ($handle === 'szene-3d') {
        $tag = str_replace('<script ', '<script type="module" ', $tag);
    }
    return $tag;
}, 10, 2);

Der Filter am Ende ist der Punkt, an dem die meisten scheitern: Ohne type="module" funktioniert import nicht, und die Konsole meldet einen Syntaxfehler.

In js/szene.js steht dann die eigentliche Szene. Three.js lässt sich über eine Import-Map oder als lokal abgelegte Datei laden. Lokal ist besser: schneller und ohne Datenübertragung an ein fremdes CDN.

js/szene.js (gekürzt)
import * as THREE from './lib/three.module.min.js';

const box = document.getElementById('szene-3d');
if (box) {
  // Erst starten, wenn die Szene in Sichtweite kommt
  const io = new IntersectionObserver(([e]) => {
    if (!e.isIntersecting) return;
    io.disconnect();
    starten(box);
  }, { rootMargin: '200px' });
  io.observe(box);
}

function starten(box) {
  const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
  renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
  renderer.setSize(box.clientWidth, box.clientHeight);
  box.appendChild(renderer.domElement);
  // ... Szene, Kamera, Modell
}

Das verzögerte Starten ist bei WordPress besonders wichtig, weil Themes oft ohnehin viel JavaScript laden. So kostet die 3D-Szene keine Ladezeit, bis sie gebraucht wird.

Weg 2: Eigener Gutenberg-Block.

Sinnvoll, wenn Redakteure die Szene selbst platzieren und Einstellungen wie Modell, Höhe oder Hintergrund im Editor ändern sollen. Mehr Aufwand in der Entwicklung, dafür die sauberste Lösung für Teams, die ohne Code arbeiten.

Weg 3: Eigenständige App per iframe.

Bei großen Anwendungen wie Konfiguratoren lohnt es sich oft, die 3D-App getrennt zu betreiben und in WordPress einzubetten. So beeinflussen sich Theme und Anwendung gegenseitig nicht. Genau so ist die Horizont-Baureise aufgebaut.

Typische Konflikte mit WordPress.

  • Optimierungs-Plugins fassen JavaScript zusammen und zerstören dabei Module. Die 3D-Datei von der Minifizierung ausnehmen.
  • Doppeltes Three.js: Zwei Plugins laden jeweils eigene Versionen — Warnung in der Konsole, merkwürdiges Verhalten.
  • Page-Builder-Container haben beim Laden noch die Höhe 0. Die Größe per ResizeObserver nachführen.
  • GLB-Upload blockiert: WordPress lässt den Dateityp standardmäßig nicht zu. Erlauben oder per FTP ablegen.
Häufige Fragen

FAQ — Three.js in WordPress einbinden.

Kann ich Three.js in WordPress ohne Plugin nutzen?

Ja, und das ist meist die sauberere Lösung. Das Skript wird im Child-Theme über wp_enqueue_script registriert und nur auf den Seiten geladen, die die Szene zeigen, etwa über einen Shortcode oder einen eigenen Block.

Warum funktioniert import in meinem WordPress-Skript nicht?

WordPress gibt Skripte standardmäßig ohne type="module" aus. Ohne dieses Attribut erkennt der Browser import nicht und meldet einen Syntaxfehler. Über den Filter script_loader_tag lässt sich das Attribut für das eine Skript ergänzen.

Wie lade ich GLB-Dateien in WordPress hoch?

WordPress erlaubt den Dateityp standardmäßig nicht. Er lässt sich über den Filter upload_mimes freischalten, alternativ legt man die Modelle per FTP im Theme- oder Upload-Verzeichnis ab.

Macht Three.js meine WordPress-Seite langsam?

Nur, wenn es falsch eingebunden ist. Wird das Skript ausschließlich auf den betreffenden Seiten geladen und erst gestartet, wenn die Szene sichtbar wird, hat es auf die Ladezeit der übrigen Seite kaum Einfluss.

Funktioniert das auch mit Elementor?

Ja, über einen Shortcode-Widget oder ein eigenes Widget. Elementor-Container haben beim Laden allerdings manchmal noch keine Höhe, weshalb die Größe der Szene über einen ResizeObserver nachgeführt werden sollte.

Manuel Killert (rechts im Bild) mit einem FreundDas bin ich – rechts im Bild
Kontakt

Erzähl mir, was du zeigen willst.

Ich sage dir ehrlich, ob sich 3D für dein Vorhaben lohnt — und wenn nicht, was stattdessen mehr bringt.

Antwort meist innerhalb von 24 Stunden · hallo@manuelkillert.de