tenbruggencate / shopware-analytics
Multi-backend analytics integration for Shopware 6 with TrackerInterface abstraction
Package info
bitbucket.org/Bruggencate/sw-plugin-analytics/
Type:shopware-platform-plugin
pkg:composer/tenbruggencate/shopware-analytics
Requires
- php: >= 8.2
- shopware/core: ~6.7.0
- shopware/storefront: ~6.7.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.94
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.0
This package is not auto-updated.
Last update: 2026-04-27 23:10:32 UTC
README
TenBruggencateAnalytics
![]()
Multi-backend analytics for Shopware 6. Ships a TrackerInterface abstraction plus two production-ready adapters (Matomo + Plausible); plug in any other backend by implementing the interface. Cookieless by default. GDPR-first defaults.
License: MIT · Shopware: 6.7.x · PHP: 8.1 / 8.2
🇬🇧 English · 🇳🇱 Nederlands · 🇩🇪 Deutsch
📖 More context: Why we built this · How it compares
What it does
Most analytics plugins for Shopware are single-backend ("Matomo plugin", "GA plugin", "Plausible plugin"), which forces a lock-in: switching backend means uninstalling one plugin and learning another. This plugin separates "what to track" from "where to send it":
TrackerInterface— stable contract (emitHeadScript(),emitBodyEnd(),trackEvent(...)) that any backend implementsTrackerRegistry— admin picks the active backend from a list; switching is a config change, not a reinstall- Bundled adapters — Matomo (was formerly its own plugin, folded in so shop owners install one thing) and Plausible
- Cookieless by default — no cookies set unless the admin explicitly opts in
Install
composer require tenbruggencate/shopware-analytics
bin/console plugin:refresh
bin/console plugin:install --activate TenBruggencateAnalytics
bin/console cache:clear
Configuration
Configurable per sales channel from Settings → System → Plugins → Analytics.
| Field | Default | Purpose |
|---|---|---|
enabled | true | Kill switch for all tracker emission |
trackerType | matomo | matomo or plausible (or any custom tracker registered via services.xml) |
matomoUrl | — | Your Matomo endpoint (when trackerType=matomo) |
siteId | — | Matomo site ID |
cookielessMode | true | Matomo disableCookies toggle |
ipAnonymization | true | Drop last octet before storage |
respectDoNotTrack | true | Honour the browser's DNT header |
trackAdminUsers | false | Don't pollute stats with admin browsing |
brandDimensionId | 0 | Matomo custom-dimension ID to record brandKey (when used with TenBruggencateMultiBrand) |
pageTypeDimensionId | 0 | Dimension ID for page-type labels (home / plp / pdp / checkout) |
stoneSlugDimensionId | 0 | Example of how to wire a further custom dimension — rename / repurpose as needed |
Usage
The tracker renders itself into every storefront page. No template work needed.
Adding a new backend — implement TrackerInterface:
final class UmamiTracker implements TrackerInterface
{
public function getKey(): string { return 'umami'; }
public function emitHeadScript(SalesChannelContext $ctx): string { /* ... */ }
public function emitBodyEnd(SalesChannelContext $ctx): string { return ''; }
public function trackEvent(string $event, array $properties): void { /* ... */ }
}
Register it in your plugin's services.xml with the ten_bruggencate_analytics.tracker tag and it appears in the admin dropdown.
Standards
- Performance — single inline script in
<head>, ~1.5 KB when Matomo is configured, ~0.4 KB for Plausible. No external library fetch until the user has interacted (cookieless flow). - SEO — tracker emission does not touch meta tags, URLs, canonicals, or sitemaps.
- GDPR — cookieless / DNT-respecting / IP-anonymised defaults ship
true. Track-admin-users defaults tofalse. Includes aMigration<ts>CopyMatomoConfigthat forward-migrates existing settings from the deprecated standalone Matomo plugin (see TEN-159). Full data-flow + subject-rights documentation inGDPR.md. - WCAG — tracker output is an inline script; no visual or interaction surface. Rationale + structural guarantees documented in
docs/ACCESSIBILITY.md. - Security — all configured URLs are validated as HTTPS in the admin config form. No eval, no dynamic script injection, no third-party CDN fetch until the admin turns off cookieless mode.
- Uninstall —
plugin:uninstall --keep-user-datapreserves tracker config (Matomo URL, site IDs, dimensions);plugin:uninstallwithout the flag also drops any legacyTenBruggencateMatomo.config.*rows from the old standalone plugin (TEN-159). No owned tables — analytics data lives on the configured backend, not in this shop.
Compatibility
Core platform
| Shopware | PHP | Status |
|---|---|---|
| 6.7.x — tested against 6.7.8, 6.7.9 | 8.1, 8.2 | Stable |
| 6.6.x | — | Not supported |
| 6.5.x and earlier | — | Not supported |
Database
| Engine | Version | Notes |
|---|---|---|
| MySQL | 8.0+ | Primary target; JSON functions used for config-row manipulation in migrations |
| MariaDB | 10.11+ | Tested end-to-end; earlier versions lack some JSON operator support |
Browsers (storefront)
Evergreen browsers only — the two most recent stable releases of each:
| Browser | Desktop | Mobile |
|---|---|---|
| Chrome / Chromium | ✅ | ✅ |
| Firefox | ✅ | ✅ |
| Safari | ✅ (macOS) | ✅ (iOS 16+) |
| Edge | ✅ | — |
Internet Explorer and legacy Edge are not supported. The plugin emits no runtime JS (where applicable) so graceful degradation on older browsers usually still renders content, just without progressive enhancements.
Admin browsers
Same evergreen matrix — the Shopware admin is Vue-based and has its own compatibility baseline that this plugin doesn't extend or narrow.
Development
| Tool | Version | Scope |
|---|---|---|
| PHP | ≥ 8.1 | Runtime + test suite |
| Composer | 2.x | Dependency management |
| Node.js | ≥ 18 | Only needed if you edit SCSS and re-run the theme compile |
| Python | ≥ 3.9 | Only needed for the repo's asset-pipeline scripts (scripts/*.py) |
Accessibility
WCAG 2.2 level A + AA — see docs/ACCESSIBILITY.md for axe-core audit output and per-page violations.
What we test before each release
- Full PHPUnit unit suite against PHP 8.1 + 8.2 (source-inspection tests don't need a kernel)
- PHPStan level 8 + PHP-CS-Fixer (@PSR12 + @Symfony)
- Composer validate on every plugin
- Live-DB smoke tests (plugin install → activate → route render → uninstall cycle)
- axe-core audit on the primary storefront surfaces (see ACCESSIBILITY.md)
Related plugins
Part of the TenBruggencate Suite — small, focused plugins that play well together:
- MultiBrand — provides the
brandKeythatbrandDimensionIdrecords, so Matomo reports can slice by brand without needing separate site IDs. - Maintenance — maintenance page renders with tracker disabled (no analytics noise during downtime).
- LegalPages — Dutch / German / English legal page templates. Privacy page is the natural target for the Cookie Notice / DPA reference.
- NewsletterLite — GDPR-safe newsletter signup that pairs naturally with privacy-first analytics.
Migration from the standalone Matomo plugin
If you previously used tenbruggencate/shopware-matomo, upgrade is automatic. Two migrations run on plugin:install --activate TenBruggencateAnalytics:
Migration1713225600CopyMatomoConfig— mirrorsTenBruggencateMatomo.config.*rows intoTenBruggencateAnalytics.config.*Migration1776530000RemoveOrphanedMatomoPlugin— defensive cleanup of the now-unused plugin registry row
No admin reconfiguration needed; tracking continues uninterrupted.
Support
- Email: guy@tenbruggencatedevelopment.nl
- Docs & news: tenbruggencatedevelopment.nl
- Source / issues: Bitbucket repo
- Security vulnerabilities: see
SECURITY.md— email first, no public issues, 72-hour acknowledgement SLA