Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Statamic Consent Manager Laravel Package

eminos/statamic-consent-manager

A consent management addon for Statamic that lets you collect and manage cookie and tracking consent, with configurable consent groups and a frontend banner to help keep your site GDPR-compliant.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish in three commands:

composer require <vendor>/laravel-consent
php artisan vendor:publish --tag="consent-config"
php artisan migrate

Then look at these three places, in this order:

  1. config/consent.php — the consent categories/groups (e.g. necessary, analytics, marketing), cookie lifetime, and the middleware/route settings. This is the file you will edit most.
  2. routes/web.php (package routes) — the package registers a ConsentManagerController that handles showing the banner/manager and persisting a submission. Run php artisan route:list | grep -i consent to see exactly which URIs and names it owns before you build your own.
  3. The published migration + consent model — consent records are stored per subject (user or anonymous session/visitor token) with the accepted categories and a timestamp. This is your audit trail; treat it as append-only.

First use case: drop the banner into your layout and record a consent decision.

{{-- resources/views/layouts/app.blade.php, just before </body> --}}
@include('consent::banner')
// app/Http/Controllers/CheckoutController.php
if (! consent()->allows('marketing')) {
    // don't load the pixel / don't pass the email to the ad platform
}

Verify the round trip in the browser: accept only "necessary", reload, and confirm the consent cookie/record reflects that and that gated scripts do not load.

Implementation Patterns

Gate third-party scripts, not just the banner. The banner is the easy part; the value is in making all non-essential loading conditional. Wrap analytics/marketing snippets in a Blade conditional or a small ConsentService call so that consent state is the single source of truth:

@if (consent()->allows('analytics'))
    <script src="{{ asset('js/analytics.js') }}" defer></script>
@endif

Resolve consent per request via middleware. Register the package middleware on the web group so the current consent state is available to views and controllers without passing it around. Keep a consent()->allows('category') helper (or the package's equivalent) as the only API your app code touches — that way a future package upgrade only affects the integration layer.

Log to your own table, not just the cookie. Cookies get cleared; your audit record does not. On the consent.updated-style event (or by overriding the controller's persist step), write a row with subject id/visitor token, categories accepted, policy version, IP, and user agent. Add a policy_version column now — GDPR-style re-consent on policy change is the request you will get next year, and retrofitting it is painful.

Re-consent on version bump. Store the accepted policy version alongside the categories and invalidate consent when config('consent.policy_version') changes. This is the cleanest way to force the banner to reappear for returning visitors without touching the DB by hand.

Override the controller rather than forking it. Since v2.0.2 touches ConsentManagerController, you want to be able to take patches. Point the package route at your own controller (or extend the package controller and override only the method you need), so you can add validation, redirect handling, or custom response formats without editing vendor code.

Test the negative path. Feature tests should assert that a visitor without consent does not receive the marketing tags, and that a POST to the consent endpoint without a valid category list is rejected — those are the two regressions that actually cost money.

Gotchas and Tips

PHP 8.4: pin >=2.0.2. v2.0.2 fixes an implicit-nullable parameter deprecation in ConsentManagerController (Type $param = null → ?Type $param = null). On PHP 8.4 with deprecations promoted to exceptions (common in test suites and in APP_DEBUG CI runs), earlier 2.0.x will fail loudly. Keep the constraint at ^2.0.2 and re-run your test suite after upgrading — the change is behaviourally a no-op, but anything that subclassed or reflected over that controller signature should be re-checked.

Cache/session drivers. If consent state is cached per visitor, remember php artisan cache:clear after changing cookie names or category keys, otherwise the banner silently never reappears in testing and you'll chase a bug in your Blade.

Route and middleware ordering. Consent middleware must run after session/authentication middleware, or you'll resolve consent for the wrong subject identity. If you have a custom web group, confirm the package middleware sits after StartSession.

Publishing assets twice. Re-publishing config on upgrade can overwrite local edits. Keep your diff of config/consent.php in version control and prefer env-driven values for anything you'd otherwise hardcode.

Server-side vs client-side consent drift. The banner JS may write the cookie before the POST reaches the server (or vice versa on failure). Make the server record authoritative for gating, and treat the cookie as a cache — this prevents the "user opted out but analytics fired anyway" audit finding.

Extension points worth knowing. Look for the package's events, the consent model's HasConsents-style trait (attach to User), and the view namespace — those three are the intended customisation seams. Anything else is effectively vendor code; prefer overriding at the route/controller/view level so patch releases like 2.0.2 land cleanly.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names