Bilder, JavaScript und andere Theme-Assets ausliefern
Alles im Ordner public/ eines Themes ist im Storefront unter /themes/<vendor>/<name>/<path> verfügbar. Das ist der einzige URL-Präfix, der für Theme-Assets funktioniert. Das ist mit Abstand die häufigste Ursache für Fehler nach dem Muster „Das Bild liefert in der Produktion einen 404-Fehler“, also solltest Du diese Konvention frühzeitig verinnerlichen.
Der URL-Aufbau
Eine Datei unter custom/themes/hw/mytheme/public/img/hero.png wird unter /themes/hw/mytheme/img/hero.png ausgeliefert. Das Segment public/ wird entfernt, und Vendor sowie der kleingeschriebene Theme-Name werden vorangestellt.
custom/themes/hw/mytheme/
└── public/
├── css/ → /themes/hw/mytheme/css/*
├── js/ → /themes/hw/mytheme/js/*
├── img/ → /themes/hw/mytheme/img/*
└── fonts/ → /themes/hw/mytheme/fonts/*Das Vendor-Segment ist erforderlich. Ein Pfad, der es überspringt (/themes/mytheme/img/hero.png), liefert immer einen 404-Fehler, unabhängig davon, wie die Ordnerstruktur auf der Festplatte aussieht.
Ein Asset aus Twig referenzieren
Verwende den Laravel-Helper asset() mit dem theme-relativen Pfad. Hänge ?v={{ hwCacheId }} an, damit der Browser-Cache bei der nächsten Kompilierung oder Aktualisierung ungültig wird.
<img src="{{ asset('themes/hw/mytheme/img/hero.png') }}?v={{ hwCacheId }}" alt="Hero">
<script src="{{ asset('themes/hw/mytheme/js/menu.js') }}?v={{ hwCacheId }}" defer></script>Fest codierte Pfade (<script src="/themes/hw/mytheme/js/menu.js">) funktionieren ebenfalls, umgehen aber die App-URL und den Cache-Buster. Bevorzuge asset().
Ein Asset aus SCSS referenzieren
Verwende dieselbe absolute URL, ein Helper ist nicht erforderlich. Die Ausgabe der Kompilierung liegt unter /assets/css/; relative url()-Pfade würden daher dorthin aufgelöst und nicht relativ zu Deiner SCSS-Quelldatei.
body {
background-image: url("/themes/hw/mytheme/img/bg.png");
}Der Cache-Buster
hwCacheId ist eine globale Twig-Variable, die sich jedes Mal ändert, wenn das Theme-CSS neu kompiliert oder das Branding gespeichert wird. Eine Änderung daran zwingt den Browser, geänderte Stylesheets, Scripts und Bilder erneut abzurufen. Jeder vom Theme ausgegebene Asset-Link sollte sie als Query-String enthalten, sonst sieht ein Kunde nach einem Deployment weiterhin Dein altes CSS.
JavaScript-Konventionen
Lege Scripts unter public/js/ ab und lade sie aus dem Twig-Template, das sie benötigt. Bevorzuge defer, damit das Script auf das DOM wartet, ohne die Seite zu blockieren.
<script src="{{ asset('themes/hw/mytheme/js/evo-slider.js') }}?v={{ hwCacheId }}" defer></script>Wenn mehrere CMS-Elemente vom selben Script abhängen (zum Beispiel ein Slider, der von Header und Testimonials verwendet wird), füge das Script-Tag in ein gemeinsames Twig-Partial ein und binde es in jedes Element ein, das es benötigt. Browser entfernen identische <script src>-Tags aus Duplikaten, sodass ein Element, das auf einer Seite fünfmal gerendert wird, sein Script nur einmal herunterlädt.
Schriftarten
Schriftarten, die der Admin im Branding-Tab auswählt, werden automatisch heruntergeladen, unter /public/assets/fonts/system/<slug>/ gespeichert und über @font-face-Regeln referenziert, die die Kompilierungspipeline in das Theme-CSS schreibt. Du musst sie weder selbst ausliefern noch referenzieren.
Liefere eine Schriftart nur dann manuell aus, wenn das Theme auf eine feste Schriftart angewiesen ist, die nicht der Auswahl des Admins folgen darf. Lege die woff2-Dateien unter public/fonts/ ab und definiere @font-face in Deinem SCSS.
Jede Theme-Asset-URL muss das Vendor-Segment enthalten. /themes/hw/mytheme/img/logo.png funktioniert; /themes/mytheme/img/logo.png ist fehlerhaft. Das passiert fast jedem mindestens einmal.