jostkleigrewe / cookie-consent-bundle
Symfony 8 bundle for GDPR/DSGVO cookie consent with Google Consent Mode v2, Twig components, Stimulus.js, and AssetMapper. Supports cookie, Doctrine, or combined storage. Includes YouTube, Vimeo, Google Maps embed components.
Package info
github.com/jostkleigrewe/cookie-consent-bundle
Type:symfony-bundle
pkg:composer/jostkleigrewe/cookie-consent-bundle
Fund package maintenance!
Requires
- php: >=8.4
- psr/log: ^3.0
- symfony/asset: ^8.0
- symfony/asset-mapper: ^8.0
- symfony/config: ^8.0
- symfony/console: ^8.0
- symfony/dependency-injection: ^8.0
- symfony/framework-bundle: ^8.0
- symfony/http-foundation: ^8.0
- symfony/http-kernel: ^8.0
- symfony/security-csrf: ^8.0
- symfony/security-http: ^8.0
- symfony/stimulus-bundle: ^2.0
- symfony/twig-bundle: ^8.0
- symfony/ux-twig-component: ^2.0
Requires (Dev)
- doctrine/dbal: ^4.0
- doctrine/orm: ^3.6
- phpstan/phpstan: ^1.11
- symfony/browser-kit: ^8.0
- symfony/phpunit-bridge: ^7.1
- symfony/security-bundle: ^8.0
Suggests
- doctrine/dbal: For database-backed consent storage (DBAL adapter)
- doctrine/doctrine-bundle: Optional: enables Doctrine integration and storage backends
- doctrine/orm: Optional: enables ORM-backed consent storage and audit logging
- symfony/security-bundle: Optional: enables user-based audit logging via the security token storage
README
A modern Symfony 8 bundle for GDPR/DSGVO-compliant cookie consent management. Includes Google Consent Mode v2 support, Twig components, Stimulus.js integration, and AssetMapper compatibility. Perfect for cookie banners, consent modals, and privacy-compliant websites.
๐ฉ๐ช Deutsche Version ยท ๐ฆ Packagist ยท ๐ Documentation
Why this bundle?
- โ Symfony-native consent handling with Twig, Stimulus, and AssetMapper
- โ Vendor-level toggles + Consent Mode v2 for modern ad stacks
- โ Session-safe by design: prevents unwanted session cookies
Screenshot
Features
- ๐ฏ GDPR & DSGVO Compliant โ Cookie consent with policy versioning and audit logging
- ๐ Google Consent Mode v2 โ Built-in GA4, Google Ads, and gtag integration
- ๐จ Multiple Themes โ Tabler (light/dark), Bootstrap 5, or custom templates
- โก Stimulus.js & Turbo โ Hotwire-compatible, no full page reload needed
- ๐๏ธ AssetMapper Ready โ No Webpack/Encore required, works out of the box
- ๐งญ Flexible Storage โ Cookie-only, Doctrine ORM, or combined (hybrid)
- ๐งฉ Vendor-Level Consent โ Optional per-vendor toggles (Google Ads, Meta, etc.)
- ๐ก๏ธ Session Protection โ Prevents session cookies without explicit consent
- ๐ฌ Embed Components โ YouTube, Vimeo, Google Maps, Spotify, Instagram, TikTok with consent gates
- ๐งช Twig Helpers โ
cookie_consent_has(),cookie_consent_modal(), and more - ๐ Audit Logging โ Track consent changes with optional database persistence
Requirements
- PHP 8.4+
- Symfony 8.0+
- Twig Bundle, Security Bundle, Stimulus Bundle
- Doctrine ORM + DoctrineBundle (optional, only for
storage: doctrine|both)
Compatibility
| Bundle Version | PHP | Symfony |
|---|---|---|
| 0.4.x | 8.4+ | 8.0+ |
| 0.3.x | 8.3+ | 7.1+ |
| 0.2.x | 8.2+ | 7.0+ |
Quick Start
1. Install
composer require jostkleigrewe/cookie-consent-bundle
2. Register routes
Create config/routes/cookie_consent.yaml:
cookie_consent: resource: '@CookieConsentBundle/config/routes.php'
This registers the /_cookie-consent endpoint required for consent updates.
3. Configure assets
Option A: Twig helper (CSP-compatible, recommended)
{# templates/base.html.twig - in <head> #}
{{ cookie_consent_styles() }}
This renders a standard <link> tag, fully compatible with strict Content-Security-Policy headers.
Option B: JavaScript import
// assets/app.js import '@jostkleigrewe/cookie-consent-bundle/styles/cookie_consent.css';
Note: With strict CSP (
style-src 'self'), bundlers may convert CSS imports todata:URLs, which can be blocked. Use Option A if you encounter CSP issues.
// assets/controllers.json { "controllers": { "@jostkleigrewe/cookie-consent-bundle": { "cookie-consent": { "enabled": true, "fetch": "eager" } } } }
4. Render the modal
{# templates/base.html.twig #}
{{ cookie_consent_modal() }}
5. Gate content by consent
{% if cookie_consent_has('analytics') %}
<script src="https://example.com/analytics.js"></script>
{% endif %}
Or use lazy loading:
<script type="text/plain" data-consent-category="analytics" data-consent-src="https://example.com/analytics.js"></script>
Configuration
Create config/packages/cookie_consent.yaml:
cookie_consent: policy_version: '1' storage: cookie # cookie, doctrine, or both categories: necessary: label: Necessary required: true default: true analytics: label: Analytics default: false marketing: label: Marketing default: false vendors: google_ads: label: Google Ads default: false ui: template: '@CookieConsent/styles/tabler/modal.html.twig' position: center privacy_url: '/privacy' reload_on_change: false logging: retention_days: null google_consent_mode: enabled: false
Storage Modes
| Mode | Description | Use Case |
|---|---|---|
cookie |
Browser cookie only (default) | Simple sites, no DB required |
doctrine |
Database only via Doctrine ORM | Server-side consent verification |
both |
Cookie + Database (cookie as primary, DB as backup) | Full audit trail + fast access |
If storage is set to doctrine or both, generate migrations in your app (bundle ships entities, not migrations). This requires Doctrine ORM:
bin/console doctrine:migrations:diff bin/console doctrine:migrations:migrate
Increment policy_version when changing categories to require re-consent.
If logging.retention_days is set, run the cleanup command regularly:
bin/console cookie-consent:cleanup
Documentation
- Getting Started - Installation, assets, first steps
- Configuration - All options, templates, Twig helpers
- Advanced - Storage backends, session enforcement, logging, events
- Integration - Components, helpers, attributes, data attributes, events
- Changelog - Releases and notable changes
- Contributing - Development workflow and guidelines
Embed Components
Gate third-party content with built-in components:
<twig:CookieConsentYoutubeEmbed video_id="dQw4w9WgXcQ" category="marketing" vendor="youtube" />
Alternative:
{{ component('CookieConsentYoutubeEmbed', {
video_id: 'dQw4w9WgXcQ',
category: 'marketing',
vendor: 'youtube'
}) }}
Available: YouTube, Vimeo, Google Maps, Spotify, Twitter/X, Instagram, TikTok, and more.
Integration Overview
See Integration for Twig components, helpers, data attributes, controller attributes, and events.
Troubleshooting
Modal doesn't appear
- Ensure
{{ cookie_consent_modal() }}is in your base template - Check browser console for JavaScript errors
- Verify Stimulus controller is loaded:
@jostkleigrewe/cookie-consent-bundle/cookie-consent
Assets not loading (404)
- Run
bin/console cache:clear - Check AssetMapper paths:
bin/console debug:asset-map | grep cookie - Ensure
assets/app.jsimports the CSS
Session cookie created before consent
- Check
enforcement.require_consent_for_sessionistrue - Add routes to
stateless_routesif they should work without session - Verify
#[ConsentStateless]attribute on stateless controllers
Doctrine storage not working
- Run migrations:
bin/console doctrine:migrations:diff && bin/console doctrine:migrations:migrate - Check
storage: doctrineorstorage: bothis set - Verify
doctrine/ormanddoctrine/doctrine-bundleare installed
Google Consent Mode not updating
- Ensure
google_consent_mode.enabled: true - Check
gtagis loaded before the consent modal - Verify category mapping matches your categories
Tabler variant styling issues (missing border-radius, labels below checkbox)
- Cause: Tabler loads after bundle CSS and overrides
.modal-contentandform-switchstyles - Solution: Update to latest bundle version (>= 0.4.2) which includes Tabler-specific fixes
- Manual fix: Add to your CSS with higher specificity:
.cookie-consent-modal.cookie-consent-variant-tabler .modal-content { border: 0; border-radius: var(--cc-radius, 18px); box-shadow: var(--cc-shadow, 0 24px 60px rgba(15, 23, 42, 0.25)); } .cookie-consent-variant-tabler .cookie-consent-toggle.form-switch { display: block; padding-left: 2.5rem; } .cookie-consent-variant-tabler .cookie-consent-toggle.form-switch .form-check-input { float: left; margin-left: -2.5rem; }
Contributing
composer install composer ci
License
MIT - see LICENSE.
Resources
Keywords
Symfony cookie consent, GDPR cookie banner, DSGVO cookie modal, Google Consent Mode v2, Symfony 8 bundle, cookie management, consent management platform, CMP, Twig cookie component, Stimulus.js cookie, AssetMapper, Doctrine consent storage, YouTube embed consent, privacy compliance, e-privacy.
