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 sinds 25 juni 2026 vereist

Richtlijn (EU) 2023/2673, die een herroepingsfunctie toevoegt aan de richtlijn consumentenrechten, verplicht webshops die aan consumenten verkopen tot een herroepingsknop in twee stappen (in Nederland art. 6:230oa BW, sinds 25 juni 2026). Stap 1 luidt «Hier de overeenkomst herroepen», stap 2 «Herroeping bevestigen» (de Nederlandse tekst van de richtlijn; de Nederlandse wet schrijft geen vaste tekst voor, alleen een ondubbelzinnige formulering). Daartussen staat een formulier voor de naam, de gegevens van de overeenkomst en het e-mailadres voor de ontvangstbevestiging, gevolgd door een ontvangstbevestiging per e-mail op een duurzame gegevensdrager.

Geen login, opvallend geplaatst en gemakkelijk toegankelijk, beschikbaar gedurende de volledige bedenktermijn. Bij overtredingen kan de ACM handhaven en, als klanten niet over de herroepingsfunctie zijn geïnformeerd, loopt 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. Maak voor elk domein het liefst een aparte shop-vermelding in het WiderrufButton-dashboard aan, zodat herroepingen en statistieken aan de juiste shop worden toegewezen. 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 op elke pagina bereikbaar en duidelijk uitgelicht
  • 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.

Start je gratis proefperiode

14 dagen gratis · geen creditcard · daarna vanaf 2,99 €/maand · altijd opzegbaar