Laravel Cookie Consent
Consent banner middleware with a proof-of-consent log.
composer require devix-labs/laravel-cookie-consent
Live demo coming soon
The browser widget writes a first-party JSON cookie; this package reads it in Laravel. Ask Consent::allows('analytics'), wrap a tag in @consent, and it is never printed unless it is allowed — stronger than printing it and blocking it in the browser. A decision made against an older policy version stops counting the moment you bump the config. The proof-of-consent log writes one row per decision and per change of mind, with the IP stored as an HMAC rather than in the clear.
What you get
The decision, in PHP
Consent::allows('analytics'), 'analytics/ga4' or a bare service id — plus the whole decision: what was refused, how, under which regime, in which language.
@consent in Blade
Wrap the script tag. A tag that is not allowed is never sent to the browser at all.
One tag renders the widget
<x-cookie-consent /> brings your categories, your policy link, the visitor's country from your CDN header and the call that logs the decision.
Proof you own
A row per decision and per change of mind: consent id, categories, refusals, version, regime, language, notice hash, revision — and the IP as an HMAC, never in the clear.
Policy versioning that bites
Bump the version and the server stops honouring consent given to wording that no longer applies, the same moment the widget starts asking again.
The encryption trap, handled
Laravel encrypts cookies it sets; this one is written by JavaScript. The provider excepts it automatically — the usual reason a server-side consent check silently answers no.
Laravel Cookie Consent — overview
Why it exists
A consent banner in the browser can only block what the browser can see. When the decision is readable on the server, a tag that is not allowed is never printed at all — and the proof of what was agreed to lives in your database, not in a third party's dashboard.
What it does
- Reads the decision. The widget writes a first-party JSON cookie; this package parses it, checks
it against your current policy version, and answers
Consent::allows('analytics'). - Gates tags in Blade.
@consent('analytics')around the script tag. - Renders the widget. One
<x-cookie-consent />with your categories, your policy URL and the visitor's country from your CDN header. - Keeps the log. One row per decision and per change of mind: consent id, categories, refusals, version, regime, language, notice hash, revision, hashed IP, user agent, and when.
Not in 1.0
A Nova/Filament screen for the log, and consent receipts by email, are deliberate omissions. The
browser widget is a separate product: @devix/cookie-consent.
How it compares
Questions
How is this different from spatie/laravel-cookie-consent?
That package shows a banner and remembers that it was dismissed. It blocks nothing and there is nothing to ask on the server. This one reads an actual decision — categories, services, refusals — so you can decide in PHP whether a tag is printed, and it keeps the log.
Do I need the JavaScript widget too?
Yes — the browser is where consent is given. This package renders it for you with <x-cookie-consent /> and reads what it wrote. You can serve the widget from your own Vite build.
Why is my consent check always false?
Almost always Laravel's cookie encryption: the widget writes the cookie from JavaScript, so Laravel cannot decrypt it. This package excepts the cookie automatically — if you renamed it in the config, that exception follows the new name.
Does this work with full-page caching?
Not if the HTML varies by consent — include the decision in your cache key, or print the tags with data-cc and let the widget release them in the browser. The docs show both.
Is the log personal data?
It is written to be the least it can be: the consent id links to the visitor's own cookie, and the IP is stored as an HMAC with your APP_KEY. Trim old rows on a schedule — the docs show that too.
More from Devix
All resources →Laravel Phone
Laravel package
Phone validation, casts and a Blade component that agree with Phone Input exactly.
Laravel Validators
Laravel package
Validation rules for regional IDs, tax numbers and IBANs.
Invoice PDF
Laravel package
VAT-ready invoice PDFs with Arabic and Urdu support.