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

Laravel Cookie Guard Laravel Package

scify/laravel-cookie-guard

Laravel Cookie Guard is a configurable cookie consent package for Laravel. It adds a GDPR-friendly banner, lets visitors accept or reject cookie categories, remembers their choices, and helps load scripts conditionally through simple Blade helpers and middleware.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Require the package with Composer, then publish everything you need:
    php artisan vendor:publish --tag="cookies-consent-config"
    php artisan vendor:publish --tag="cookies-consent-public"
    php artisan vendor:publish --tag="cookies-consent-translations"
    
  • Look first at the published config (config/cookies_consent.php) — it holds the category list, each category's named cookies, the required list, cookie_prefix, cookie_lifetime, and use_separate_page. Everything the banner renders is driven from here.
  • Drop the banner component into your layout, just before </body>, so it renders on every page that can set cookies:
    <x-cookies-consent::banner />
    
  • Typical first task: declare your app's cookie categories so that rejecting a category actually deletes things. A category only erases cookies if the cookie names are listed under its name key — the package walks the host and its parent domains down to the registrable domain on rejection.
  • If you need a full-page consent screen instead of the corner banner, set use_separate_page and render the separate-page component; in v5.1 both banner variants render the category list onto the root element, so "Accept all" and "Reject optional" now behave correctly there.

Implementation Patterns

Banner vs. separate page. Pick one per app: the inline banner for the common case, use_separate_page when legal wants a dedicated consent wall. Both are Blade components with the same contract, so your tests can assert on the same root attributes.

Opening the banner on demand. Link to #consent-settings from your footer ("Cookie settings") — in 5.1 a hash change after load opens the banner rather than toggling it, and a[href="#consent-settings"] links do the same. That means a sitewide footer link is now a safe, idempotent way to let users revisit consent.

SPA stacks (Inertia, Livewire, Turbo). You no longer need to do anything: the save request sends the XSRF-TOKEN cookie as X-XSRF-TOKEN, so the token stays valid on pages that never do a full reload. If you were patching the JS to refresh a stale token, drop that patch.

Posting to the save route yourself. POST /guard-settings/save now runs in the web middleware group with CSRF enforcement. Any custom form or fetch call must send a token — X-XSRF-TOKEN, X-CSRF-TOKEN, or the _token field. Payload shape is one boolean per configured category plus locale; unknown keys are discarded, so sending extra metadata is harmless but pointless.

Custom markup. If you've replaced the package view, keep the root attributes the JS reads: data-cookie-lifetime, data-cookie-categories, data-required-categories, and data-csrf-token (fallback chain is root attribute → csrf-token meta tag).

Translations. Publish into lang/vendor/cookies_consent/{locale}/messages.php and keep only the keys you changed — Laravel merges vendor translations key by key, so untouched strings keep receiving upstream fixes. Swedish is sv; the se directory is gone.

Consent lifetime. cookie_lifetime is what the browser actually stores (it used to be a hardcoded 30 days that disagreed with both the config and the banner copy). Set 0 for a session-scoped consent cookie — good for shared/kiosk machines.

Testing. Pest covers config-driven Blade output and view overrides; the JS bundle is tested with node:test. Mirror that: assert root data attributes in a feature test, and assert cookie erasure on rejection by hitting your own routes after a consent POST.

Gotchas and Tips

  • Upgrading means re-publishing twice. --tag="cookies-consent-public" --force for the JS, and re-publish the Blade views (or hand-add the four data-* attributes). With pre-5.1 markup the JS silently falls back to 365 days and erases nothing on rejection — a failure with no error.
  • 419s after upgrade. If your own code posts to /guard-settings/save, it was previously unauthenticated by accident. Add the token. On Laravel 13 same-origin requests without a token are still accepted, which can mask the bug in dev and surface it behind a proxy.
  • 422s. Any category value that isn't a boolean fails validation. Cast from form inputs ($request->boolean() on your side) or send proper JSON booleans.
  • enabled is gone. Remove it from your published config; it never did anything, but leaving it invites someone to "turn the banner off" and be confused.
  • Old translation directory still loads with a log warning until v6. Watch storage/logs/laravel.log after upgrading; if you see the warning, you still have strings in lang/vendor/scify/laravel-cookie-guard/.
  • Locale rename. Apps using se must switch to sv or fall back to another locale's strings.
  • Required categories can't be withdrawn. They're always stored as accepted server-side, and rejection never touches their cookies. Don't try to make strictly_necessary optional — put genuinely optional cookies in a separate category.
  • The banner stays open on a failed save. That's intentional; make sure your error path (offline, 500) doesn't look like a frozen page. The JS hides the banner only after the server confirms.
  • Separate-page mode was broken before 5.1 — "Accept all" stored no optional categories. If you added a workaround (custom JS posting the full selection, or a hidden form), remove it or you'll double-submit.
  • Two cookies stopped being written: the server-side {cookie_prefix}cookies_consent_selection (which never reached a browser anyway) and the pre-v3 cookieConsent cleanup. If any of your code reads the former, it was always empty — delete the branch. If you still have users with the ancient cookieConsent cookie, expire it yourself.
  • Hash behaviour changed from toggle to open. If you built a "close the banner" affordance around #consent-settings, it no longer closes it.
  • SameSite=Lax + Secure on HTTPS is now set on the consent cookie. If you front the site with a TLS-terminating proxy, make sure TrustProxies is configured or Secure may be omitted on requests Laravel thinks are HTTP.
  • Extension points: the cleanest customization is publishing and overriding the Blade views, then the translations, then (last resort) the JS bundle. There's no event or resolver layer — don't expect one, and don't reach into the route handler.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle