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

Alt Cookies Laravel Package

alt-design/alt-cookies

Alt Cookies is a lightweight Laravel package for cookie consent management. Publish config and Blade views, sort cookies into categories, and conditionally load scripts so your site stays GDPR-friendly without heavy JavaScript dependencies.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm the basics first. This is a Statamic addon (not a plain Laravel package), so treat it as a Statamic extension: it registers a service provider, likely a tag/partial for the banner, a config file, and some front-end JS. With only 4 stars and no dependents, budget 20 minutes to read src/, resources/views/, config/, and routes/ before wiring anything into a client site — the README is likely thin compared to the code.

Decide which line you're on before touching Composer. As of v1.3.2-alpha there are two lines: stable 1.2.x and the 1.3 pre-release. Composer will not install an alpha unless you ask for it, so a plain composer require keeps you on 1.2. The 1.3 line is where the cookie scan, no-reload consent application, and updateConsent() live — pin it explicitly if you want them:

composer require alt-design/alt-cookies:^1.3@alpha   # or an exact 1.3.2-alpha pin
composer show alt-design/alt-cookies                 # confirm version + autoload path

Minimal path:

  1. Install and verify discovery

    composer show alt-design/alt-cookies   # confirm version + autoload path
    

    Statamic auto-discovers addons; check the CP's Addons list or php please support:details if the provider doesn't appear.

  2. Publish config (and views if you'll restyle)

    php artisan vendor:publish --tag=alt-cookies-config
    php artisan vendor:publish --tag=alt-cookies-views
    

    If those tags don't exist, run php artisan vendor:publish interactively and pick the provider — confirm the exact provider namespace from composer.json's extra.statamic.providers.

  3. Set the GA measurement ID in the published config or the addon's CP settings screen (whichever it exposes). Prefer an env var (ALT_COOKIES_GA_ID) so staging doesn't pollute production analytics. On 1.3 also set the default consent state here rather than in JS — the release fixes a double-load of that default, so it should now be a single source of truth.

  4. Run the cookie scan on staging before writing any banner copy. On 1.3 the Alt Cookies settings page (and the dashboard) gains a scan tab that crawls the site's pages in a headless browser to catch JS-set cookies, not just Set-Cookie headers. Do this first: it tells you which cookies exist and therefore how many categories you actually need. Generate the policy copy from the report, then edit it — it is a formatted draft for Bard, not a legal document.

  5. Render the banner once, in your base Antlers layout, immediately before </body>. The addon will expose either a tag (e.g. {{ alt_cookies }} / {{ alt_cookies:banner }}) or a partial — check src/Tags/ for the registered handle rather than guessing.

  6. First use case: gate GA4 behind consent on a marketing site, with a "manage preferences" entry point. Load the page in incognito, confirm no gtag/js request until you accept, then accept and confirm the script fires without a reload (1.3 behaviour; 1.2 reloads). Check the consent cookie in DevTools → Application → Cookies, then follow the generated policy's preferences link and confirm it reopens the banner with the current choice preselected.

If the site is Blade-first rather than Antlers, check whether the addon ships a Blade component/directive; otherwise include the tag via {{ Statamic::tag('alt_cookies') }} or render the published partial directly.

Implementation Patterns

Banner inclusion is a layout concern, not a page concern. Put it in resources/views/layout.antlers.html (or your Blade base layout). Duplicating it into individual templates is the fastest way to get double banners and double consent writes.

Let the scan drive your category model. The 1.3 scanner report is the cheapest source of truth for "what are we actually setting" — server and JS cookies in one list. Convert that list into categories in config, then map scripts to categories. Re-run the scan after adding any third-party integration; it's a far better regression check than eyeballing Network tab.

Use the no-reload apply, but know what it does and doesn't cover. 1.3 applies accept/reject without a page reload. That's fine for the addon's own managed scripts. Any script you inject yourself (custom pixels, embeds, chat widgets) won't automatically re-run — call the new updateConsent() after your own state changes so the addon stays the authority. Since updateConsent() is new in 1.3, feature-detect it (typeof updateConsent === 'function') if you maintain a theme that spans both lines.

Don't hand-roll gtag in the layout. The whole value of the package is that the GA snippet is emitted conditionally. If you paste the standard Google snippet into your <head>, you've defeated the addon and created a GDPR problem. If you need GTM instead of raw GA, wire it through the addon's script config, or use Consent Mode: default everything to denied inline, then push consent.update from the addon's accept handler.

Ship a persistent preferences entry point. The generated policy copy includes a link hook for reopening the banner — wire that hook into the actual banner (usually a JS call or a data- attribute on the link). Put "Cookie preferences" in the footer of every page; regulators and clients both expect consent to be as easy to withdraw as to give.

Static caching changes the design. If you use Statamic's static cache or a full-page CDN cache, never render consent state server-side. The banner markup must be cacheable and the accept/decline logic must be client-side. The 1.3 no-reload behaviour helps here — no reload means no chance of a cached page serving stale consent markup — but it does not remove the requirement that the default state be client-side.

Multi-environment and multisite. Never run the cookie scan against production: it crawls pages, warms caches, and can trip rate limits, form submissions, or outbound API quotas. Scan staging behind the same basic auth you use for the client. On multisite, prefer one shared policy with per-site banner copy via translations (lang/en/alt-cookies.php style) rather than per-site config drift.

Testing workflow for day-to-day work:

  • Incognito window per test; clear the consent cookie between runs.
  • DevTools → Network, filter collect / gtag to prove nothing fires pre-consent.
  • Accept, then confirm scripts start firing with no navigation, and that a reload preserves the choice.
  • Verify the cookie's expires, SameSite, and Secure attributes match your policy wording.
  • Add one browser-level smoke test (Dusk/Playwright) covering accept → assert script present → reload → assert still present. With no dependents, this is your regression net.

Gotchas and Tips

  • Alpha means alpha. v1.3.2-alpha is a pre-release; Composer won't pick it up implicitly, and it won't be a stability risk to your other sites unless you ask for it. Pin the exact version (1.3.2-alpha) in composer.json rather than ^1.3@alpha if the client site is live — a later 1.3.x-alpha can land under you otherwise.
  • Upgrade risk is low but asymmetric. Nothing in the public JavaScript API has been removed or renamed since 1.2.7 or 1.3.1-alpha, so 1.2.x → 1.3.2-alpha and 1.3.1 → 1.3.2 are both additive. The risk is entirely in your code: updateConsent() doesn't exist on 1.2, so guard it.
  • Remove your double-load workaround. 1.3 fixes the default consent state being loaded twice. If you patched around duplicate initialisation (a guard flag in a custom script, a filtered view), delete it or you'll be debugging a fix that no longer applies.
  • The scan is a crawler, not a linter. It observes cookies set by JS as well as server responses, which means it renders your pages in a real browser. Expect session cookies, CSRF cookies, and anything set by your own admin toolbar to show up in the report — prune those from the categories before generating policy copy.
  • Generated policy copy is a first draft. It's formatted to paste cleanly into Bard and will read better than most hand-written attempts, but it describes what the scanner saw on the pages it visited. Pages behind auth, gated content, and post-form-submission states are invisible to it. Get it reviewed before publishing, and re-run the scan when you add an integration.
  • Low adoption = sparse docs and few bug reports. Pin the version, read the changelog before minor bumps, and diff published views after upgrades. Assume you are the first person to hit edge cases — particularly around the scanner on non-standard setups (multisite, subdirectory installs, heavy JS frameworks).
  • Config cache bites. After editing the addon config, run php artisan config:clear. In production, config:cache will freeze the GA ID, cookie name, and default consent state — which is usually what you want, but it makes "why didn't my change deploy" a five-minute mystery.
  • View override precedence. Published views live under resources/views/vendor/{namespace}/. Clear the view cache (php artisan view:clear) after overriding, and remember Statamic's Antlers runtime cache if the markup still looks stale. Your published banner view is the thing most likely to break the "reopen preferences" link hook after an upgrade — check it whenever you bump.
  • Cookie name collisions and flags. If you already set a cookie_consent cookie from a previous agency, you'll get two competing banners. Behind a load balancer, ensure TrustProxies is configured or Secure/SameSite flags will silently misbehave.
  • CSP. If you enforce Content-Security-Policy, the addon's inline bootstrap script needs a nonce or hash. Check whether it supports a nonce attribute; otherwise move the inline portion to an external file in public/. The 1.3 no-reload apply makes this more visible — previously a reload could mask a blocked inline script.
  • Live Preview and the CP. Consent banners frequently leak into Live Preview or the control panel. Add the addon's middleware/tag exclusion for cp and preview routes, or conditionally render on Statamic::isCp() / the preview session. Also confirm the scanner tab itself isn't crawling CP URLs or triggering the banner recursively.
  • Ad blockers and DNT will make your "it doesn't fire" debugging misleading. Test in a clean profile with extensions disabled before filing anything upstream.
  • GA4 vs. legacy UA and Consent Mode v2. If you serve EEA/UK traffic, plan for Consent Mode v2 signals (ad_user_data, ad_personalization) — a simple accept/decline banner from a 4-star addon may not emit them. This is the most likely place you'll need to extend rather than configure.
  • Extension points to reach for, in order: publish and override the banner view → translations → config array of scripts/categories → the scan report as your category source → a small custom tag that wraps the addon's consent service → updateConsent() for scripts you load yourself → forking the tag. Avoid patching vendor/.
  • Debugging checklist when consent "doesn't work": cookie actually written? (document.cookie in console) → addon JS enqueued once, not twice? → script emitted but blocked by CSP? → your own scripts applied via updateConsent() or still waiting for a reload? → page served from static cache with stale inline state? → config cached with the wrong ID? → scan report stale, so a cookie is uncategorised and silently skipped? Work that list in order; it resolves most issues in under ten minutes.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
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