lemric/cookie-consent-bundle
A Symfony bundle for adding a cookie consent banner to your application. It helps you present cookie notices, collect visitor consent, and manage preferences, supporting GDPR-style compliance without hand-rolling a consent flow. Lightweight and quick to configure in any Symfony app.
Reality check first: this is a Symfony bundle, not a Laravel package. There is no Lemric\CookieConsentBundle\CookieConsentServiceProvider, no config/cookie-consent.php, and no vendor:publish tags. Composer will install it into a Laravel app just fine, but nothing will auto-register. So your day-one decision is architectural, not technical:
config/bundles.php. This is the only path where "using the package" means what its author intended.src/, lift the consent-banner JS/CSS and the consent-state model, and reimplement the server-side bits as a Laravel package of your own (service provider, config file, Blade component, middleware). The bundle's total logic is small enough that porting is cheaper than bridging Symfony's DI container into Laravel's.Where to look first, in this order:
composer.json — required Symfony version, whether it pulls symfony/framework-bundle, twig, doctrine/*. This tells you how heavy a bridge would be.src/DependencyInjection/Configuration.php — the config tree. This is the de-facto documentation for this package; with 0 stars there is no README worth trusting more than the code.src/Resources/config/ — service definitions: what the consent service is called, what it injects, whether there's a controller or a Twig extension.src/Resources/views/ — the banner markup. Note the template namespace (@LemricCookieConsent/...) because that's also the override path.src/Resources/public/ (or assets/) — the JS that writes/reads the consent cookie. This is the piece you'll actually reuse in Laravel.First use case to validate end-to-end: render the banner on a fresh session → click "Accept analytics" → confirm a consent cookie is written with a category payload → confirm a server-side request to a page that outputs an analytics snippet now includes it. If you can't get that loop working in an afternoon, the package isn't saving you time.
Category-based gating, not a single boolean. The useful shape for AVG/GDPR is necessary | analytics | marketing | preferences, with necessary always on and the others opt-in. Whatever the bundle exposes, normalize to a category array in the consent cookie payload (e.g. {"v":1,"cats":["necessary","analytics"],"ts":...}). Gate on category, never on "did they click accept."
Server-side gate before the script tag, not after. The pattern that actually holds up:
@if (app(\App\Support\Consent::class)->allows('analytics'))
<script src="{{ mix('js/analytics.js') }}"></script>
@endif
Rendering the tag with a type="text/plain" and letting JS rewrite it works too, but it leaks the request and is easy to get wrong. Prefer the server-side check plus a thin client-side check for SPA routes.
Laravel middleware for the state, not a global helper. If you port this, make ResolveCookieConsent middleware parse the consent cookie once, validate the version, and bind a Consent object into the container. Controllers, Blade, and Livewire then all read the same source of truth, and you get a natural test seam ($this->withCookie(...)).
Consent versioning and re-prompting. Put a schema/policy version in the cookie. When you bump it (new vendor, new purpose), treat old cookies as absent and re-prompt. This is the single most-forgotten GDPR requirement and the bundle likely doesn't do it for you unless you wire it.
Audit trail in the database. A banner alone doesn't demonstrate consent. Log (user_id|null, consent_id, version, categories, ip_hash, user_agent, granted_at, withdrawn_at) on every change. For Laravel: a consents table + an event listener; for Symfony: a Doctrine entity + an event subscriber on the bundle's consent event (check src/Event/ for the dispatched event name — that's your extension point).
Withdrawal must be as easy as granting. A persistent "Cookie settings" link in the footer that reopens the banner and lets the user downgrade. The bundle's JS usually exposes a reopen hook; if not, call the same function the banner's settings button calls.
Cross-domain / subdomain consistency. Set the consent cookie on .example.com with SameSite=Lax (or None; Secure if you're embedding across sites), and match Path=/. Mismatched scope is the #1 cause of "the banner keeps reappearing."
templates/bundles/LemricCookieConsentBundle/<template>.twig in the app.bin/console assets:install --symlink or an importmap entry — there's no vendor:publish. If you're porting to Laravel, copy the assets into resources/ and run them through Vite rather than serving from vendor/.config/packages/lemric_cookie_consent.yaml. Read Configuration.php before you assume a key exists; the array node names are the API.nl and en at minimum. Confirm before you hardcode English strings in an override template, or you'll silently lose the other locales.analytics, assert the analytics <script> is absent from the HTML. That single test catches most regressions from a refactor.composer.json requires symfony/framework-bundle: ^6.x and you're on 7, you'll get resolution conflicts. In Laravel this doesn't matter (you're porting), but it does if you go the bridge route.Path/Domain in devtools, then check whether the bundle's template renders at all by hitting its route/controller directly. 90% of the time it's a stale cookie from a previous config.How can I help you explore Laravel packages today?