tenbruggencate / newsletter-lite
Shopware 6 newsletter signup: GDPR-safe with double opt-in, opaque-token unsubscribe with email erasure, per-IP rate limit.
Package info
bitbucket.org/Bruggencate/sw-plugin-newsletter-lite
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
Suggests
- tenbruggencate/newsletter-pro: Campaigns, automations & segmentation (paid)
- dev-main
- 1.11.0
- 1.10.3
- 1.10.2
- 1.7.1
- 1.7.0
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.0
- 1.4.1
- 1.4.0
- dev-docs/cross-promotion
- dev-feat/subscriber-sales-channel
- dev-docs/readme-branding
- dev-chore/reposition-newsletter-lite
- dev-docs/reposition-lite-pro-family
- dev-chore/refresh-screenshots-v1.10.3
- dev-fix/admin-dal-timestamps-v1.10.2
- dev-docs/readme-admin-module
- dev-feat/subscriber-admin-module
- dev-feat/audit-improvements
- dev-feat/admin-config-improvements
- dev-chore/docs-screenshots-v1.7.1
- dev-chore/ux-polish-v1.7.0
- dev-chore/packagist-description-and-screenshot-cleanup
- dev-fix/scss-autoload-and-doc-refresh
- dev-feat/double-opt-in
- dev-feat/subscribe-rate-limit
- dev-chore/trigger-packagist-webhook
- 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 auto-updated.
Last update: 2026-05-18 01:37:28 UTC
README
Newsletter Lite
![]()
Own a clean, GDPR-safe subscriber list. Newsletter Lite is the genuine free tool for capturing and managing newsletter subscribers in Shopware 6: a standalone subscriber table, opaque-token unsubscribe with one-click email erasure, double opt-in by default, and a searchable admin list with CSV export. No third-party dependencies. None of Shopware's built-in newsletter UX-customisation pain.
It does one thing, and does it well — get consent-clean subscribers into a list you control, and let you get them back out again (CSV export) for whatever you send them with.
▲ Newsletter Pro adds campaigns, lifecycle automations (abandoned-cart, back-in-stock, win-back) and native-data segmentation built on your shop's own order data. Pro requires this plugin and installs it automatically — see Part of a Lite/Pro family below.
License: MIT · Shopware: 6.7.x · PHP: 8.1 / 8.2
🇬🇧 English · 🇳🇱 Nederlands · 🇩🇪 Deutsch
📖 More context: Why we built this · How it compares
Screenshots
Landing page — desktop |
Landing page — mobile (responsive) |
Admin — subscriber management — searchable list, CSV export, double-opt-in status badges |
|
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,confirmed+ DOI token columns,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
- Double opt-in by default (v1.6+) — new signups receive a confirmation email; rows only flip to
confirmed=1after the visitor clicks the link. 24h token expiry. Existing pre-DOI subscribers grandfathered as already confirmed. Single-opt-in remains available via therequireDoubleOptInconfig toggle if you have a deliberate reason to use it - Origin / volume / consent triple-defence on the subscribe endpoint — cross-origin POSTs rejected (v1.4.1), per-IP rate limit (v1.5.0, 5 attempts / 10 min), and DOI for proof-of-consent (v1.6.0)
- Admin subscriber list (v1.10.0) — a "Newsletter subscribers" module under the Marketing menu: search by email, sortable columns, a per-row confirmed / pending / unsubscribed status, and one-click CSV export. Backed by a read-only DAL entity — the opaque tokens and consent IP hash are never exposed through the admin API
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.
Production-readiness checklist
A deliberately short list of things to verify before enabling the plugin on a customer-facing storefront. Not legal cover — the MIT license already disclaims warranty — but practical guidance an experienced operator would want anyway.
- [ ] Database backup before upgrading or uninstalling. The plugin owns one table; a backup makes the destructive uninstall path reversible.
- [ ] SMTP wired up before flipping
requireDoubleOptInon. v1.6.0+ defaults DOI to on; without working mail transport, visitors submit the form, get the "check your inbox" page, and never receive a confirmation email — they're stuck inconfirmed=0forever. If you can't configure SMTP yet, setrequireDoubleOptIn=falseuntil you can. - [ ] Privacy policy URL set in the plugin config. The form's fineprint links to it; an empty URL routes to a 404 and trains visitors to ignore privacy notices.
- [ ] Test on staging before production. Especially the unsubscribe + DOI confirm flows — both rely on per-row tokens that depend on
random_bytes()being available (always is, on any modern PHP, but verify). - [ ] Trusted proxies configured if you're behind a CDN / load balancer. v1.5.0+ rate-limits per client IP; without
trusted_proxiesset, every visitor shares the same proxy IP and the limit fires too aggressively.
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)
Part of a Lite/Pro family
Newsletter Lite is the free tier of a Lite/Pro plugin family. It is a complete, standalone tool — capturing and managing a clean subscriber list is the whole job, and nothing here is gated or crippled to push an upsell.
Newsletter Pro (sold separately) builds on the list Lite gives you and adds the sending side: campaign composition, lifecycle automations (abandoned-cart, back-in-stock, win-back, post-purchase) and behavioural segmentation built on your shop's own order data. Pro requires this plugin and installs it automatically. It is brand-new and still in development — if all you need today is a consent-clean subscriber list, Newsletter Lite on its own is the right tool.
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.
More from Ten Bruggencate Development
Focused, privacy-first Shopware 6 plugins — free to start, upgrade when you grow:
- Newsletter — Lite: GDPR-safe signup & subscriber-list management · Pro: campaigns, lifecycle automations, native-data segmentation
- Legal Pages — Lite: localized legal-page templates · Pro: the compliance toolkit (maintained templates, cookie policy, accessibility statement)
- Analytics — multi-backend (Matomo / Plausible), GDPR-first, cookieless-capable
- Maintenance — a branded, SEO-correct maintenance page
- Multi-Brand — serve multiple brands from one Shopware, by hostname
- Product Encyclopedia — structured educational content pages linked to products
- Seasons — scheduled theme-config variants
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