DEV Community

Cover image for EU shop rules: what developers need to change this weekend
luca kingsley
luca kingsley

Posted on

EU shop rules: what developers need to change this weekend

If you build or maintain online shops for EU customers, three rules changed this year, and one of them starts tomorrow, Sunday 27 September 2026. Here's what they mean in code, plus two gotchas I ran into while implementing them for WooCommerce.

Not legal advice. Everything below is from the official sources linked at the end.

1. The EU legal guarantee notice (from 27 September 2026)

Every seller of goods to consumers in the EU has to show a harmonised notice about the legal guarantee. You don't design it: the European Commission publishes one official sheet (blue header, short text, QR code) in all 24 EU languages, as SVG, PNG and PDF.

What the Commission's practical guidelines require online:

  • the official file, in colour, unchanged: no recolouring, cropping, changing fonts or touching the QR code
  • legible at default display size
  • always a clickable link to the same destination as the QR code
  • displayed "prominently", for example a sentence like "Your legal guarantee rights" that opens the notice on the first click
  • also in the order confirmation email

The simplest markup that works everywhere, even inside site builders that sandbox your HTML in an iframe:

<details class="eu-guarantee">
  <summary>Your legal guarantee rights</summary>
  <a href="/eu-guarantee-en.svg" target="_blank" rel="noopener">
    <img src="/eu-guarantee-en.svg" width="595" height="842"
         alt="EU notice on the legal guarantee: goods sold in the EU come with a legal guarantee of conformity of at least two years."
         style="display:block;width:100%;max-width:595px;height:auto">
  </a>
  <p><a href="https://europa.eu/youreurope/guarantees" target="_blank" rel="noopener">europa.eu/youreurope/guarantees</a></p>
</details>
Enter fullscreen mode Exit fullscreen mode

Host the file yourself instead of hotlinking. Each language has its own link target (German is europa.eu/youreurope/garantien, French .../garanties, and so on).

Gotcha 1: the WooCommerce checkout block ignores the classic hooks. Since WooCommerce 8.3 new shops get the block checkout by default, and woocommerce_review_order_before_submit simply never fires there. The inner part is rendered by React, so HTML you inject inside it can disappear. What worked for me is placing it right before the block:

add_filter( 'render_block_woocommerce/checkout', function ( $html ) {
    return '<div class="eu-guarantee-checkout">' . my_notice_html() . '</div>' . $html;
} );
Enter fullscreen mode Exit fullscreen mode

Gotcha 2: SVG in emails. Many mail clients don't render SVG, so use the Commission's PNG for the order email. Curiously, the PNG package has 23 languages and is missing English, which only exists as SVG and PDF. For English emails I fall back to the sentence plus link.

2. The withdrawal button (since 19 June 2026)

Directive (EU) 2023/2673 added a "withdrawal function" for contracts concluded online. Germany implemented it in Β§ 356a BGB. The flow is fixed:

  1. a clearly labelled "withdraw from contract" button or link, available during the whole withdrawal period
  2. a short form: name, which contract/order, where to send the confirmation
  3. a second button, "confirm withdrawal"
  4. an immediate acknowledgement on a durable medium (in practice an email) with the content of the withdrawal and the date and time it was received

According to the German legislative reasoning, it should be reachable from every page, must not force a login if customers can order as guests, and must not ask for a reason. Shopify, Shopware, JTL and the German legal plugins for WooCommerce ship implementations; check the version you're on.

The part nobody tests is step 4. Actually submit a test withdrawal and read the email: does it contain the date and the time? Does it say which order? Wording like "your withdrawal is hereby confirmed" is discouraged: say it was received.

3. Green claims (from 27 September 2026)

Directive (EU) 2024/825 adds several claims to the list of practices that are always banned towards consumers, for example:

  • generic environmental claims ("eco-friendly", "green", "climate friendly") without recognised excellent environmental performance
  • "climate neutral" and similar claims based on offsetting emissions
  • self-made sustainability labels that aren't based on a certification scheme
  • claims about the whole product when they're only true for a part

For developers this is mostly a content audit, but a catalogue with hundreds of products needs tooling. One detail if you grep product texts in JavaScript: \b doesn't treat umlauts as word characters, so \bΓΆkologisch never matches. Unicode-aware boundaries do:

const before = '(?<![\\p{L}\\p{N}])';
const after = '(?![\\p{L}\\p{N}])';
const rule = new RegExp(`${before}(?:umweltfreundlich|eco-friendly)\\p{L}*${after}`, 'giu');
Enter fullscreen mode Exit fullscreen mode

A hit means "check this", not "banned": whether "climate neutral" is illegal depends on whether it rests on offsetting.

Tools

I put all of this into a small, free hub, one chapter per rule with sources and dates:

  • Shop rules check: enter a shop URL, see what's there and what's missing
  • Ad copy checker: paste texts or a Shopify/WooCommerce CSV export; runs in the browser
  • Notice builder: the official file in 24 languages with ready-made code

πŸ‘‰ https://kingsley-ym.de/en/shop-rules

I'd love to hear what breaks: false positives, shop systems I got wrong, anything.

Sources

Top comments (0)