Blog · Shopware 6

Herroepingsknop in Shopware 6. Gratis tutorial met code.

Shopware 6-handelaren werken met Twig, Symfony en een netjes gescheiden storefront-architectuur. Dat is goed nieuws, want het stelt ons in staat de herroepingsknop netjes via een plugin in te haken, zonder core-bestanden aan te raken. Hier is het volledige pad.

Wat de wet vanaf 19 juni 2026 vereist

Richtlijn (EU) 2023/2673, die een herroepingsfunctie toevoegt aan de richtlijn consumentenrechten, verplicht elke B2C-shop in de EU tot een herroepingsknop in twee stappen. Stap 1 luidt «Overeenkomst herroepen». Stap 2 luidt «Herroeping bevestigen». Daartussen staat een formulier met naam plus een contactmiddel als verplichte velden, gevolgd door een ontvangstbevestiging per e-mail op een duurzame gegevensdrager.

Geen login, geen scroll-barrière. Beschikbaar gedurende de volledige bedenktermijn. Het risico op een ingebrekestelling bij overtredingen ligt doorgaans tussen 500 en 2.000 EUR, plus een automatische verlenging van de bedenktermijn tot twaalf maanden en veertien dagen.

De twee wegen voor Shopware 6

Weg A: een Twig-template-extensie rechtstreeks in je thema. Snel, maar gebonden aan je thema. Bij thema-updates moet je opletten.

Weg B: je eigen storefront-plugin die een Twig-snippet registreert. Netjes, update-veilig en uit te schakelen via de admin. Dit is de aanbevolen Shopware-weg.

Weg A: Twig-template-extensie in het thema

Shopware 6 gebruikt blok-gebaseerde Twig-templates. Je kunt elk blok overschrijven of uitbreiden. De footer staat in @Storefront/storefront/layout/footer/footer.html.twig. We haken in op het blok base_footer_inner_container.

{# Resources/views/storefront/layout/footer/footer.html.twig #}
{% sw_extends '@Storefront/storefront/layout/footer/footer.html.twig' %}

{% block base_footer_inner_container %}
    {{ parent() }}

    <script
        src="https://widerrufbutton.net/widget/v1/wh.js"
        data-shop-id="{{ config('WiderrufButton.config.shopId') }}"
        data-position="footer"
        data-lang="de"
        async
        defer
    ></script>
{% endblock %}

De aanroep config(...) benadert de plugin-configuratie. Als je geen configuratie wilt opbouwen, kun je de widgetsleutel ook rechtstreeks in de snippet schrijven. Voor een nette oplossing heb je echter weg B nodig.

Weg B: je eigen plugin

Een Shopware 6-plugin is in wezen een Symfony-bundle met een composer.json, een plugin-klasse en een services.xml voor dependency injection.

De minimale structuur ziet er zo uit:

custom/plugins/WiderrufButton/
├── composer.json
├── src/
│   ├── WiderrufButton.php
│   ├── Resources/
│   │   ├── config/
│   │   │   ├── config.xml
│   │   │   └── services.xml
│   │   └── views/
│   │       └── storefront/
│   │           └── layout/
│   │               └── footer/
│   │                   └── footer.html.twig

De config.xml definieert het invoerveld voor de widgetsleutel in de Shopware-admin:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/trunk/src/Core/System/SystemConfig/Schema/config.xsd">
    <card>
        <title>WiderrufButton</title>
        <input-field>
            <name>shopId</name>
            <label>Widget-Key</label>
            <helpText>Aus dem WiderrufButton-Dashboard</helpText>
        </input-field>
    </card>
</config>

De services.xml blijft leeg zolang je geen eigen services nodig hebt. De Twig-template overschrijft het footer-blok net als in weg A, maar roept de plugin-configuratie aan via config('WiderrufButton.config.shopId').

Plugin activeren en testen

Voer in de Shopware-map de commando's in deze volgorde uit:

bin/console plugin:refresh
bin/console plugin:install --activate WiderrufButton
bin/console theme:compile
bin/console cache:clear

Daarna verschijnt de plugin in de admin onder Uitbreidingen. Voer daar de widgetsleutel uit je WiderrufButton-dashboard in. Opslaan. Open de shop en controleer de footer.

Let op de HTTP-cache en CSP

Shopware 6 cachet agressief. Leeg na het compileren van het thema de HTTP-cache, anders zie je het script niet meteen. In de Shopware-configuratie is dat bin/console http:cache:clear.

Als je een Content Security Policy actief hebt, moet widerrufbutton.net in de directives script-src en connect-src staan. De browser laadt het script vandaar en stuurt de herroeping naar de API-route op hetzelfde domein.

Waarom de Shadow DOM belangrijk is

Shopware-thema's brengen hun eigen CSS mee. Zonder inkapseling zou de knop-styling botsen met het thema, zouden de kleuren verkeerd worden weergegeven en zou de modal op de verkeerde plek verschijnen. Daarom draait de widget binnen de Shadow DOM. De CSS is volledig geïsoleerd, Shopware-styles kunnen niets overschrijven en je thema blijft onaangeroerd.

Hetzelfde geldt in de andere richting: de knop kan jouw thema niets aandoen. Geen globale styles, geen botsende klassenamen, geen lettertypen die onbedoeld worden overschreven.

Meertaligheid en sales channels

Shopware staat meerdere sales channels met verschillende domeinen toe. Voor elk domein heb je een aparte shop-vermelding in het WiderrufButton-dashboard nodig, zodat de CORS-controle op de juiste origin wordt uitgevoerd. De widgetsleutels verschillen, en je moet per sales channel de juiste sleutel aan de plugin-configuratie koppelen.

De details vind je op de productpagina en in de handleiding.

Checklist vóór de livegang

  • Widgetsleutel ingevoerd en opgeslagen in de admin
  • Thema opnieuw gecompileerd, HTTP-cache geleegd
  • Knop zichtbaar in de footer, bereikbaar zonder scrollen
  • Formulier verzonden met testgegevens, e-mail komt binnen seconden binnen
  • De Content Security Policy staat het widgetdomein toe
  • De testvermelding verschijnt in het dashboard onder Herroepingen

Shopware-compatibel, update-veilig, onder 15 KB

WiderrufButton werkt met elk Shopware 6-thema zonder thema-code aan te raken. Eén plugin, één widgetsleutel, klaar.

Nu gratis starten

14 dagen gratis · Geen creditcard vereist