tenbruggencate / newsletter-lite
Lightweight GDPR-safe newsletter signup for Shopware 6 โ standalone subscriber table with opaque-token unsubscribe and email erasure
Package info
bitbucket.org/Bruggencate/sw-plugin-newsletterlite/
Type:shopware-platform-plugin
pkg:composer/tenbruggencate/newsletter-lite
Requires
- php: >=8.1
- shopware/core: ~6.7
- shopware/storefront: ~6.7
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.94
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.0
- dev-main
- 1.4.1
- 1.4.0
- dev-release/v1.4.1
- dev-chore/gitignore-claude-skills
- dev-ci/junit-test-reports
- dev-polish/store-icon
- dev-polish/audit-screenshots
- dev-polish/multi-locale-docs
- dev-polish/multi-locale-changelogs
- dev-polish/why-comparison-related
- dev-fix/cross-origin-subscribe-protection
- dev-docs/clarify-token-generation
This package is not auto-updated.
Last update: 2026-04-28 15:03:14 UTC
README
TenBruggencateNewsletterLite
![]()
Lightweight GDPR-safe newsletter signup for Shopware 6. Standalone subscriber table, opaque-token unsubscribe with one-click email erasure. No third-party dependencies. No double-opt-in fight with Shopware's built-in module.
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
Shopware ships a newsletter module, but customising its UX fights the built-in flow. This plugin is deliberately smaller:
tenbruggencate_nl_subscribertable โ plainid,email,source,brand_name(server-derived โ see below),consent_given+ audit trail,unsubscribe_token,locale,subscribed_at,unsubscribed_at- Signup form partial โ drop-in Twig include with compact (footer) and full (landing) variants
- Landing page at
/newsletterโ SEO-safe, standalone, no theme dependency - Opaque-token unsubscribe โ URL carries a CSPRNG token, not the email address. One click: email gets scrubbed to
erased-<id>@newsletter.invalid, the row stays for stats - Three locales out of the box โ nl-NL, en-GB, de-DE
- No double-opt-in by default (v1).
consent_givencolumn is ready for the flip once SMTP is wired up
Install
composer require tenbruggencate/newsletter-lite
bin/console plugin:refresh
bin/console plugin:install --activate TenBruggencateNewsletterLite
bin/console database:migrate --all TenBruggencateNewsletterLite
bin/console cache:clear
Configuration
Configurable per sales channel from Extensions โ TenBruggencateNewsletterLite.
| Field | Default | Purpose |
|---|---|---|
enabled | true | Kill switch โ signup form renders nothing when off |
brandName | (empty) | Shown in headings (e.g. "Schatkistjes Club"); leave blank for generic wording |
consentText | (snippet) | Checkbox label; HTML allowed |
privacyPageUrl | /about/privacy | Link target in the fineprint |
landingPageEnabled | true | Toggle the /newsletter landing page route |
Routes
| Route | Method | Purpose |
|---|---|---|
/newsletter | GET | Landing page with signup form |
/newsletter/subscribe | POST | Handles the signup form submit |
/newsletter/unsubscribe/{token} | GET | Opaque-token unsubscribe + email scrub |
Usage
Embed the signup form anywhere via Twig:
{# Compact variant โ for footers #}
{% include '@TenBruggencateNewsletterLite/storefront/newsletter/_signup.html.twig' with { variant: 'compact' } %}
{# Default variant โ for landing pages #}
{% include '@TenBruggencateNewsletterLite/storefront/newsletter/_signup.html.twig' %}
Standards
- Performance โ no JS dependency; plain
POSTwith a 302 redirect on success. Async submission viafetch()is a ~20-line enhancement you ship in your theme if desired. - SEO โ add
/newsletter/unsubscribe/*to your theme'srobots.txtdisallow list (the landing page is indexable, the unsubscribe endpoint should not be). - GDPR โ the opaque-token pattern means the unsubscribe URL leaks nothing. One click also erases the email address from storage; the row stays for stats, PII is gone. Satisfies right-to-erasure without a manual request. Every signup writes a consent audit trail (
consent_given_at,consent_text_version,consent_ip_hash) for Article-7 supervisory audits. Full data-flow + subject-rights documentation inGDPR.md. - WCAG 2.2 AA โ semantic
<form>,<label for>,<input type=email required>, keyboard-accessible by construction. Focus state inherited from your theme. Live axe-core audit output + desktop + mobile screenshots + localised-copy evidence:docs/ACCESSIBILITY.md. - Security โ CSRF-protected via Shopware's default handler;
unsubscribe_tokenis 32 bytesrandom_bytes(). No user-controllable input in the unsubscribe SQL (token is looked up with a prepared statement). - Uninstall โ
plugin:uninstall --keep-user-datapreserves thetenbruggencate_nl_subscribertable AND everyTenBruggencateNewsletterLite.config.*row (default, recommended path when you might reinstall).plugin:uninstallwithout the flag drops the subscriber table entirely + clears config โ use this only when you genuinely want to discard all subscribers. There is no middle ground; exports happen before, not during, uninstall.
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 โ recommended: when MultiBrand is active,
brand_nameis populated automatically from the resolved brand (priority: MultiBrand resolver โ SalesChannelContext โ configuredbrandNameโ empty). Never read from the form, so tampering is impossible. Per-SC segmentation without separate sales channels. - Analytics โ signup conversions tracked automatically when Analytics is active and consent is given.
- LegalPages โ provides the
/legal/privacypage thatprivacyPageUrltypically points at. - Maintenance โ branded maintenance page that cooperates with this plugin's privacy / consent posture.
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
License
MIT ยฉ Ten Bruggencate Development