Zum Inhalt springen

Shopware 6 Theme-Entwicklung: SCSS, Twig-Override und Storefront-Anpassungen

Veröffentlicht am 25. Juni 2025 | ca. 1 Min. Lesezeit |

Die Shopware 6 Storefront basiert auf Bootstrap 5 und Twig. Themes werden als spezielle Plugins entwickelt und nutzen ein elegantes Override-System: Statt Dateien zu kopieren und zu modifizieren, überschreibt man nur gezielt die Teile, die sich ändern sollen.

Theme-Grundstruktur

Ein Theme ist ein spezielles Plugin mit einer theme.json und dem Theme-Trait:

MyTheme/
├── composer.json
├── src/
│   ├── MyTheme.php               # Plugin-Klasse mit ThemeInterface
│   └── Resources/
│       └── theme.json            # Theme-Konfiguration
│       └── app/
│           └── storefront/
│               ├── src/
│               │   ├── scss/
│               │   │   └── base.scss     # SCSS-Einstiegspunkt
│               │   └── js/
│               │       └── my-theme.js   # JS-Einstiegspunkt
│               └── views/
│                   └── storefront/       # Twig-Overrides

Plugin-Klasse

<?php

declare(strict_types=1);

namespace MyTheme;

use Shopware\Core\Framework\Plugin;
use Shopware\Storefront\Framework\ThemeInterface;

class MyTheme extends Plugin implements ThemeInterface
{
}

theme.json

{
    "name": "MyTheme",
    "author": "Wunner Software",
    "description": {
        "en-GB": "A custom Shopware 6 theme",
        "de-DE": "Ein Shopware 6 Custom Theme"
    },
    "views": ["@Storefront", "@Plugins", "@MyTheme"],
    "style": ["@Storefront", "app/storefront/src/scss/base.scss"],
    "script": ["@Storefront", "app/storefront/src/js/my-theme.js"],
    "asset": ["app/storefront/src/assets"],
    "config": {
        "blocks": {
            "colors": {
                "label": {
                    "en-GB": "Colors",
                    "de-DE": "Farben"
                },
                "fields": {
                    "sw-color-brand-primary": {
                        "label": {
                            "en-GB": "Primary color",
                            "de-DE": "Primärfarbe"
                        },
                        "type": "color",
                        "value": "#1a365d",
                        "editable": true
                    }
                }
            }
        }
    }
}

SCSS-Anpassung

Shopware Storefront nutzt Bootstrap 5. Der sauberste Weg, Styles anzupassen, ist das Überschreiben von SCSS-Variablen, bevor Bootstrap geladen wird.

base.scss — Variable überschreiben

// Eigene Variablen VOR dem Storefront-Import
$primary: #1a365d;
$secondary: #3182ce;
$font-family-base: 'Inter', system-ui, sans-serif;
$border-radius: 0.375rem;

// Shopware SCSS-Variablen überschreiben
$sw-color-brand-primary: $primary;
$sw-color-brand-secondary: $secondary;

// Eigene Styles — die Storefront-Basis wird über theme.json eingebunden (siehe unten)
.my-custom-component {
    background: $primary;
    color: white;
    padding: 1rem;
    border-radius: $border-radius;
}

Eigene SCSS-Partials organisieren

// base.scss — Storefront-Basis wird über theme.json gesteuert, nicht per @import
@import "variables";
@import "components/header";
@import "components/product-card";
@import "components/checkout";
@import "pages/product-detail";
@import "pages/listing";

Twig-Override-System

Shopware verwendet ein Twig-Namespace-System. @Storefront verweist auf die Original-Storefront-Templates. Um ein Template zu überschreiben, erstellt man eine Datei an der gleichen Position im eigenen Theme.

Ein Template vollständig ersetzen

Um /vendor/shopware/storefront/Resources/views/storefront/component/product/card/box.html.twig zu überschreiben:

MyTheme/src/Resources/views/storefront/component/product/card/box.html.twig

Einen einzelnen Block überschreiben (saubererer Ansatz)

{# Datei: views/storefront/component/product/card/box.html.twig #}
{% sw_extends '@Storefront/storefront/component/product/card/box.html.twig' %}

{% block component_product_box_image %}
    <div class="my-custom-image-wrapper">
        {{ parent() }}
        <span class="badge badge-custom">NEU</span>
    </div>
{% endblock %}

sw_extends ist der Shopware-spezifische Extend-Tag, der das Theme-Vererbungssystem berücksichtigt. parent() rendert den Original-Block-Inhalt.

Template-Hierarchie verstehen

Wenn in theme.json "views": ["@Storefront", "@Plugins", "@MyTheme"] steht, wird beim Rendern in dieser Reihenfolge nach dem Template gesucht. Das eigene Theme hat die höchste Priorität.

Storefront-JavaScript

Shopware nutzt ein eigenes Plugin-System für JavaScript (nicht zu verwechseln mit PHP-Plugins). Jede interaktive Komponente wird als Storefront-JS-Plugin registriert.

// my-plugin.js
import Plugin from 'src/plugin-system/plugin.class';

export default class MyPlugin extends Plugin {
    static options = {
        animationDuration: 300,
    };

    init() {
        this._registerEvents();
    }

    _registerEvents() {
        this.el.addEventListener('click', this._onClick.bind(this));
    }

    _onClick(event) {
        event.preventDefault();
        this.el.classList.toggle('active');
    }
}

Plugin registrieren:

// my-theme.js
import MyPlugin from './my-plugin';

const PluginManager = window.PluginManager;
PluginManager.register('MyPlugin', MyPlugin, '[data-my-plugin]');

Im Twig-Template das Data-Attribut setzen:

<div data-my-plugin="true">
    <!-- Inhalt -->
</div>

Theme kompilieren und aktivieren

# Theme installieren
php bin/console plugin:install --activate MyTheme

# Theme kompilieren (SCSS + JS)
php bin/console theme:compile

# Theme einem Sales Channel zuweisen (im Admin-Bereich oder per CLI)
php bin/console theme:change --all MyTheme

Im Entwicklungsmodus mit Watcher:

# Watch-Modus für SCSS und JS — vom Projekt-Root aus starten
composer run watch:storefront
# oder bei Production-Template:
./bin/watch-storefront.sh

Häufige Fallstricke

1. Cache nicht geleert: Nach Template-Änderungen immer bin/console cache:clear ausführen.

2. sw_extends statt extends: In Shopware muss sw_extends verwendet werden, damit das Theme-Override-System korrekt funktioniert.

3. Bootstrap-Version: Shopware 6.5+ nutzt Bootstrap 5, ältere Versionen (6.4 und früher) Bootstrap 4. Variable-Namen unterscheiden sich (z.B. $primary vs. $theme-primary).

4. Asset-Cache: Geänderte Assets (Bilder, Fonts) mit bin/console asset:install und Varnish/Browser-Cache leeren.

Fazit

Shopware Themes sind gut strukturiert und bieten mit dem Block-Override-System eine elegante Möglichkeit, nur die notwendigen Teile anzupassen. Das Twig-Vererbungssystem mit sw_extends und parent() ermöglicht saubere, wartbare Anpassungen ohne Copy-Paste von kompletten Templates.

Thomas Wunner

Thomas Wunner

Fachinformatiker für Anwendungsentwicklung mit Ausbildereignungsprüfung und über 14 Jahre Erfahrung im Aufbau skalierbarer Webanwendungen mit Symfony und Shopware. Abseits der Tastatur ist Thomas als Rettungsschwimmer in der Wasserwacht aktiv, legt als DJ auf und erkundet die Umgebung auf dem Motorrad.

Kommentare

Kommentare werden von Remark42 bereitgestellt. Beim Laden werden Daten an unseren Kommentar-Server übertragen.