Logo von nextlevels
Hey!

BFSG checklist for Shopware 6: How to make your online shop accessible

What the BFSG means for online shops

Since 28 June 2025, the Barrierefreiheitsstärkungsgesetz (BFSG) has been applicable law in Germany. It transposes the European Directive European Accessibility Act (EAA) into national law and obliges operators of digital products and services - including explicitly online shops - to comply with accessibility standards. The technical reference framework is the WCAG 2.1 at conformity level AA and the harmonised standard EN 301 549.

In concrete terms, this means that every online shop that sells products or services to consumers must be designed in such a way that people with disabilities can perceive, operate, understand and robustly use it - the four POUR principles of WCAG. This applies not only to blind users with screen readers, but also to people with motor impairments, cognitive impairments or visual impairments.

The transition period has expired. Anyone who is not yet compliant is acting unlawfully. And the first warnings from competitors and associations are already in circulation.

Who is affected?

The BFSG applies to all B2C online shops that sell goods or services to end consumers in Germany. Shops based in other EU countries that serve the German market are also covered.

Exception: Micro-enterprises with fewer than 10 employees and an annual turnover or an annual balance sheet total of less than 2 million euros are exempt - but only if both criteria are met simultaneously. As soon as one is exceeded, the obligation applies.

Important: Even if you operate shops for customers as an agency, the responsibility lies with the service provider - i.e. the shop operator itself. As an agency, however, you have a duty to inform your customers and provide compliant solutions.

The 10-point BFSG checklist for Shopware 6

The following checklist covers the most critical areas that we repeatedly identify as problematic in our audits of Shopware 6 shops.

1. Check contrast ratios and adjust theme

The WCAG 2.1 AA requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text (from 18pt or 14pt bold). Many Shopware themes - especially custom themes - use trendy, bright colours that do not reach these thresholds.

In your base.scss or the theme variables:

// ❌ Before: Contrast 2.8:1
$sw-color-brand-primary: #7eb8da;

// ✅ After: Contrast 5.2:1
$sw-color-brand-primary: #2a7ab5;

// Ensure text colours
$sw-text-color: #1a1a1a; // Contrast 15.4:1 on white
$sw-text-color-secondary: #4a4a4a; // contrast 9.7:1

Use the WebAIM Contrast Checker to validate every colour combination. Don't forget: Placeholder texts in forms, badges and price details must also be compliant.

2. Alt texts for all product images

Every informative image requires a descriptive alt text. In Shopware 6, product images are integrated via the media management. Make sure that each image has a meaningful alt text in the admin under Catalogues → Products → Media.

You can ensure a fallback in the Twig template:

{% block component_product_image %}
  <img
    src="{{ media.url }}"
    alt="{{ media.alt ?: product.translated.name ~ ' - product image' }}"
    loading="lazy"
    width="{{ media.metaData.width }}"
    height="{{ media.metaData.height }}"
  >
{% endblock %}

Decorative images (backgrounds, dividing lines) are given an empty alt="" and ideally role="presentation".

3. Keyboard navigation throughout the checkout

The entire purchase process - from the shopping basket to address entry to payment confirmation - must be fully operable via keyboard. Test with Tab, Shift+Tab, Enter and Escape.

Frequent problems in Shopware 6:

  • Custom dropdown selects for country selection without keyboard support

  • Modal dialogues (e.g. address selection without focus trap

  • ). address selection) without focus trap

  • Payment method selection with custom radio buttons without role="radio"

Example of an accessible focus trap in a modal:

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

export default class FocusTrapPlugin extends Plugin {
  init() {
    this._focusableEls = this.el.querySelectorAll(
      'a[href], button:not([disabled]), input, select, textarea, [tabindex]:not([tabindex="-1"])'
    );
    this._firstEl = this._focusableEls[0];
    this._lastEl = this._focusableEls[this._focusableEls.length - 1];
    this.el.addEventListener('keydown', this._handleKeydown.bind(this));
    this._firstEl?.focus();
  }

  _handleKeydown(e) {
    if (e.key !== 'Tab') return;
    if (e.shiftKey && document.activeElement === this._firstEl) {
      e.preventDefault();
      this._lastEl.focus();
    } else if (!e.shiftKey && document.activeElement === this._lastEl) {
      e.preventDefault();
      this._firstEl.focus();
    }
  }
}

4. Forms with clear error messages

Form fields need visible <label> elements (not just placeholders), and error messages must be programmatically linked to the field.

{% block component_address_form_field_name %}
  <div class="form-group{% if formViolations.firstName %} has-error{% endif %}">
    <label for="addressFirstName" class="form-label">
      {{ 'address.firstNameLabel'|trans }}*
    </label>
    <input
      type="text"
      id="addressFirstName"
      name="firstName"
      class="form-control"
      required
      aria-required="true"
      aria-describedby="{% if formViolations.firstName %}firstName-error{% endif %}"
      aria-invalid="{{ formViolations.firstName ? 'true' : 'false' }}"
    >
    {% if formViolations.firstName %}
      <div id="firstName-error" class="invalid-feedback" role="alert">
        {{ formViolations.firstName.message }}
      </div>
    {% endif %}
  </div>
{% endblock %}

Decisive: aria-describedby links the field to the error message, role="alert" ensures that screen readers immediately read the message aloud.

5. Skip navigation and landmark roles

Keyboard and screen reader users must be able to skip repetitive navigation areas. In your base.html.twig, add the following at the top:

{% block base_body %}
  <a class="skip-link sr-only sr-only-focusable" href="#main-content">
    Skip to main content
  </a>
  <a class="skip-link sr-only sr-only-focusable" href="#footer-navigation">
    Skip to footer navigation
  </a>
  {{ parent() }}
{% endblock %}

Also make sure that semantic landmark roles are set correctly:

<header role="banner">...</header>
<nav role="navigation" aria-label="main navigation">...</nav>
<main id="main-content" role="main">...</main>
<aside role="complementary">...</aside>
<footer id="footer-navigation" role="contentinfo">...</footer>

Cookie banners are one of the most common stumbling blocks. Requirements:

  • The banner must receive the focus immediately after loading

  • All buttons must be accessible via keyboard

  • The selection must be understandable with screen-readers

  • The "Accept all" button must not be visually favoured (dark patterns)

If you use a plugin such as Consentmanager or Cookiebot, explicitly check accessibility - many providers are not yet fully compliant. Test with Tab through the entire banner and check with NVDA or VoiceOver.

7. Responsive font sizes - no fixed px

Users must be able to enlarge text to 200% without content being cut off or overlapping (WCAG 1.4.4). Use rem or em instead of px:

// ❌ Not accessible
.product-title { font-size: 14px; }

// ✅ Accessible
.product-title { font-size: 0.875rem; }

// Ensure basis
html { font-size: 100%; } // = 16px default

Test with the browser zoom function at 200% and check that all content remains legible and that there is no horizontal scrolling.

8. Video subtitles and audio description

If you use product videos or experience videos, you need captions for deaf users and ideally an audio description for blind users.

<video controls>
  <source src="/media/produkt-demo.mp4" type="video/mp4">
  <track kind="captions" src="/media/produkt-demo-de.vtt" srclang="de" label="Deutsch" default>
  <track kind="descriptions" src="/media/produkt-demo-ad.vtt" srclang="de" label="Audiodeskription">
</video>

The BFSG requires an accessibility statement that is easy to find. Create a separate CMS page and link it in the footer. The statement must include:

  • Status of compliance (fully, partially, non-compliant)

  • Known restrictions with reasons

  • Contact option for reporting barriers (feedback mechanism)

  • Reference to the responsible enforcement body

  • Date of the last check

10. Automated + manual check

Automated tools only find about 30-40% of all barriers. You need both:

Automated:

  • axe DevTools (browser extension) - finds WCAG violations directly in the DOM

  • WAVE (WebAIM) - visual representation of problems

  • Lighthouse Accessibility Audit - integrated in Chrome DevTools

Manual:

  • Complete checkout with keyboard only

  • Screen-Reader-Test with NVDA (Windows) or VoiceOver (macOS)

  • Test zoom to 200%

  • Colour simulation for various forms of colour blindness

Shopware 6-specific pitfalls

Shopware 6 provides a solid basis as a modern framework, but has specific problem areas:

Custom themes

The standard theme (Storefront) is relatively well positioned, but custom themes often break accessibility. Typical problems: missing ARIA labels in custom headers, mega menus without keyboard support, sliders without a pause button.

Shopping Experiences

The CMS blocks of Shopping Experiences are a risk. Particularly critical:

  • Image sliders: Often without alt texts, without pause function, without keyboard control

  • Image-text combinations: Text as overlay on images without sufficient contrast

  • Custom CMS blocks: Often without semantic structure

Check each CMS block individually. Create accessible alternatives if required:

{% block cms_element_image_slider %}
  <div
    class="cms-element-image-slider"
    role="region"
    aria-label="Image gallery: {{ element.config.title.value }}"
    aria-roledescription="Carousel"
  >
    <button
      class="slider-pause"
      aria-label="Pause automatic playback"
    >
      ⏸
    </button>
    {{ parent() }}
  </div>
{% endblock %}

Listing filter

The product listing filters (price slider, colour selection, property filter) are often not accessible. The price range slider is barely operable with a keyboard. Solution: Offer additional numerical input fields.

{% block component_filter_range %}
  <div role="group" aria-label="Price filter">
    <label for="price-min">Minimum price (€)</label>
    <input type="number" id="price-min" min="0" step="1" aria-valuemin="0">
    <label for="price-max">Maximum price (€)</label>
    <input type="number" id="price-max" min="0" step="1">
  </div>
{% endblock %}

Tools for the BFSG audit

Free tools

Tool

Type

Strength

axe DevTools (Free)

Browser-Extension

Precise WCAG check, few false positives

WAVE

Browser-Extension

Visual error display

Lighthouse

Chrome DevTools

Quick overview, CI/CD integration

NVDA

Screen-Reader

Real user test (Windows)

Colour Contrast Analyser

Desktop-App

Pixel-perfect contrast check

Cost-based tools

Tool

Price from

Strength

axe Monitor

approx. 500 €/month

Automated crawling of entire shops

Siteimprove

on request

Enterprise-Monitoring with dashboard

Pope Tech

approx. 30 $/month

WAVE-based monitoring

What happens in the event of non-compliance?

The consequences of non-compliance with the BFSG are considerable:

Fines

The competent market surveillance authorities of the federal states can impose fines of up to 100,000 euros. Continued violations can result in a sales ban for the products or services concerned.

Warning letters

More relevant in practice: The BFSG gives competitors and consumer protection organisations the opportunity to issue warning letters under competition law. The costs of a warning letter typically amount to 1,500-5,000 euros - per infringement. This quickly adds up in the case of systematic deficiencies.

The first law firms have already specialised in BFSG warnings. The situation is reminiscent of the GDPR warning wave of 2018 - except that the violations are technically easier to prove here.

Reputational damage

Not to be underestimated: An accessibility violation that has become public knowledge damages the brand image considerably - especially with an increasingly sensitised public.

Accessibility as an SEO advantage

Accessibility and SEO go hand in hand. Many WCAG requirements directly improve your Google ranking:

Semantic HTML

Correct heading hierarchies (h1-h6), semantic landmarks and structured content not only help screen readers, but also the Googlebot to understand your page.

Core Web Vitals

Accessible images with width//height attributes reduce Cumulative Layout Shift (CLS). Performant, lean pages without unnecessary overlay scripts improve Largest Contentful Paint (LCP) and Interaction to Next Paint (INP).

Alt texts and image search

Descriptive alt texts improve visibility in Google image search - an often underestimated traffic channel for e-commerce.

Mobile usability

Responsive font sizes, sufficient touch targets (at least 44×44px) and a logical tab order improve the mobile user experience - a direct ranking factor.

Conclusion: Accessibility is no longer an option

The BFSG makes accessibility a legal obligation. But it is much more than compliance: it improves the user experience for all customers, strengthens your SEO and protects you from costly warnings. Investing in an accessible shop pays off in many ways.

The good news is that Shopware 6, with its Twig template system and modular architecture, offers all the prerequisites for implementing accessibility properly. However, it requires expertise and a systematic approach.


We check your shop - free of charge and without obligation

Are you unsure whether your Shopware 6 shop is BFSG-compliant? We carry out a free initial audit and show you specifically where there is a need for action.

👉 More about our e-commerce services

.services

👉 Our shopware expertise in detail

Contact us now - before the warning lawyer does.

More insights like this?

Once a month: the most important updates from e-commerce, AI & tech — straight to your inbox. Concise, honest, no spam.