The starting situation
From 19 June 2026, every B2C shop in the EU needs a withdrawal button. The legal basis is Directive (EU) 2023/2673, which adds Article 11a to the Consumer Rights Directive (2011/83/EU), transposed into national law in each member state. There is no transition period.
The button needs two stages: „Withdraw from contract“ as the entry point, „Confirm withdrawal“ at the end of the form. A short form in between, followed by an acknowledgement of receipt by email on a durable medium.
Way A: Script tag in the header
The simplest way. You add a script tag to the header area of your WordPress installation. The script loads the widget, identifies your shop via the widget key and renders the button in a Shadow DOM, without colliding with your theme CSS.
To do this you edit the header.php of your child theme. Never the parent theme's, otherwise the entry is gone after the next update.
<!-- widget/header.php, im Child-Theme -->
<?php wp_head(); ?>
<script
src="https://widerrufbutton.net/widget/v1/wh.js"
data-shop-id="<?php echo esc_attr(get_option('wrb_shop_id')); ?>"
data-position="footer"
data-lang="de"
async
defer
></script>Anyone without access to the theme can add the same script via a plugin such as „Insert Headers and Footers“. It works identically, but you have one more dependency.
Way B: functions.php filter
Cleaner than editing the header.php directly is a hook. You register a function that delivers the script via WordPress's own wp_enqueue_scripts filter. The advantage: your theme stays untouched and the entry can be disabled cleanly.
// functions.php deines Child-Themes
add_action('wp_footer', function () {
$shop_id = get_option('wrb_shop_id');
if (empty($shop_id)) {
return;
}
printf(
'<script src="https://widerrufbutton.net/widget/v1/wh.js" ' .
'data-shop-id="%s" data-position="footer" data-lang="de" async defer></script>',
esc_attr($shop_id)
);
}, 99);The priority value 99 ensures the script is loaded after all other footer scripts. This prevents caching plugins from minifying it too early.
Way C: WordPress plugin
For merchants without a developer background we are working on an official WordPress plugin. Install it, enter the shop ID, save. The button appears in the footer. The plugin will hook the script as in Way B, provide a settings page in the WP admin and add a check on whether the configured domain matches the WordPress installation.
Anyone who wants to go live today uses Way A or B. The plugin is a convenience, not a prerequisite.
Page builder conflicts
WooCommerce shops are rarely run plain. Most use Elementor, Divi, Bricks or WPBakery. Each of these builders renders footer templates independently and sometimes bypasses the standard hook flow.
Elementor: Check whether your footer is a „Theme Builder Footer“. If so, add the widget via an HTML element in the Elementor footer, not in the functions.php. Otherwise Elementor renders on top of it.
Divi: The Divi Theme Options have a „Code Integration“ field. Add script tags there, in the „Body“ section.
Bricks: Uses its own hook called bricks_body_end. Your enqueue has to target it.
Cache and security plugins
WP Rocket, WP Super Cache, LiteSpeed Cache and Autoptimize like to touch script tags. They minify, combine, delay or load them via JavaScript. With the withdrawal button this is a problem, because the button may appear too late or not load at all.
Solution: In the cache settings, exclude widerrufbutton.net from minify and combine. In WP Rocket this is „Never delay JavaScript“. In LiteSpeed, „JS Excludes“. In Autoptimize, „Exclude scripts from Autoptimize“.
Wordfence and iThemes Security can flag POST requests to external domains as suspicious. The widget sends the withdrawal to our API, not from your server. The request goes from the customer's browser directly to us, so there should be no conflict. If there is anyway: whitelist widerrufbutton.net.
Check that the install really works
Open your shop in incognito mode. Don't scroll. The button must be visible in the navigation or footer. Click it. The modal must appear without a scroll jump. Type a test name, a test email, click „Confirm withdrawal“. You should receive an email within seconds.
In the WiderrufButton dashboard, the test withdrawal appears under Withdrawals. Delete the test entry afterwards to keep your statistics clean.
What the law requires technically
The button must be reachable without scrolling, which in practice means „above the fold“ in the navigation or visible footer. It must be available throughout the entire withdrawal period, so at least fourteen days from receipt of goods. The shop must not require a login.
The acknowledgement of receipt must follow without undue delay, contain the full wording of the withdrawal declaration, including date and time, and be delivered on a durable medium. An email is enough. A toast popup is not.
Everything technically necessary behind that is handled by the widget: validation, rate limiting (10 requests per minute per IP), CORS cross-check against your registered domain, mail delivery, long-term archiving with a hash chain. Details on this in the withdrawal button guide.
Warning-letter risk and extended withdrawal period
If the button is missing, two mechanisms kick in. Competition associations send warning letters that typically cost 500 to 2,000 EUR. And the withdrawal period automatically extends to twelve months and fourteen days. A customer can then withdraw for a whole year.
Both risks are avoidable by adding the button today.