From 8b4d137a28b301c29f23757e9738bb7ac662dbcd Mon Sep 17 00:00:00 2001
From: Debatty-Tom <145542891+Debatty-Tom@users.noreply.github.com>
Date: Thu, 9 Oct 2025 10:56:33 +0200
Subject: [PATCH 1/8] Added configuration variables
---
config/cookieconsent.php | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/config/cookieconsent.php b/config/cookieconsent.php
index d22ea2a..c1b2af3 100644
--- a/config/cookieconsent.php
+++ b/config/cookieconsent.php
@@ -72,4 +72,29 @@
'anonymize_ip' => env('GOOGLE_ANALYTICS_ANONYMIZE_IP', true)
],
+ /* Google Tag Manager configuration
+ |--------------------------------------------------------------------------
+ |
+ | If you use Google Tag Manager, you can configure the package to automatically
+ | load the Google Tag Manager script when the user gives his consent.
+ |
+ | The ID parameter is required and represents your Google Tag Manager ID.
+ |
+ */
+ 'google_tag_manager' => [
+ 'id' => env('GOOGLE_TAG_MANAGER_ID'),
+ ],
+
+ /* Google Tag Manager configuration
+ |--------------------------------------------------------------------------
+ |
+ | These rules will define the data that Google Tag Manager will receive.
+ |
+ */
+ 'gtm_consent' => [
+ 'ad_user_data',
+ 'ad_personalization',
+ 'ad_storage',
+ 'analytics_storage',
+ ]
];
From 61d10bf18b10b646dd07bd391dc1fbbde1b09666 Mon Sep 17 00:00:00 2001
From: Debatty-Tom <145542891+Debatty-Tom@users.noreply.github.com>
Date: Thu, 9 Oct 2025 10:57:50 +0200
Subject: [PATCH 2/8] Added gtm method to use in the CookiesServiceProvider
---
src/AnalyticCookiesCategory.php | 72 ++++++++++++++++++++++++---------
1 file changed, 54 insertions(+), 18 deletions(-)
diff --git a/src/AnalyticCookiesCategory.php b/src/AnalyticCookiesCategory.php
index c81e936..80d29da 100644
--- a/src/AnalyticCookiesCategory.php
+++ b/src/AnalyticCookiesCategory.php
@@ -5,6 +5,30 @@
class AnalyticCookiesCategory extends CookiesCategory
{
const GOOGLE_ANALYTICS = 'ga';
+ const GOOGLE_TAG_MANAGER = 'gtm';
+
+ protected function getGroupCookies($group, $name, $id)
+ {
+ $key = str_starts_with($id, 'G-') ? substr($id, 2) : $id;
+
+ return $group->name($name)
+ ->cookie(fn(Cookie $cookie) => $cookie->name('_ga')
+ ->duration(2 * 365 * 24 * 60)
+ ->description(__('cookieConsent::cookies.defaults._ga'))
+ )
+ ->cookie(fn(Cookie $cookie) => $cookie->name('_ga_' . strtoupper($key))
+ ->duration(2 * 365 * 24 * 60)
+ ->description(__('cookieConsent::cookies.defaults._ga_ID'))
+ )
+ ->cookie(fn(Cookie $cookie) => $cookie->name('_gid')
+ ->duration(24 * 60)
+ ->description(__('cookieConsent::cookies.defaults._gid'))
+ )
+ ->cookie(fn(Cookie $cookie) => $cookie->name('_gat')
+ ->duration(1)
+ ->description(__('cookieConsent::cookies.defaults._gat'))
+ );
+ }
/**
* Define Google Analytics cookies all at once.
@@ -12,26 +36,9 @@ class AnalyticCookiesCategory extends CookiesCategory
public function google(string $id, bool $anonymizeIp = true): static
{
$this->group(function (CookiesGroup $group) use ($anonymizeIp, $id) {
- $key = str_starts_with($id, 'G-') ? substr($id, 2) : $id;
$anonymizeIp = $anonymizeIp === true ? 'true' : 'false';
- $group->name(static::GOOGLE_ANALYTICS)
- ->cookie(fn(Cookie $cookie) => $cookie->name('_ga')
- ->duration(2 * 365 * 24 * 60)
- ->description(__('cookieConsent::cookies.defaults._ga'))
- )
- ->cookie(fn(Cookie $cookie) => $cookie->name('_ga_' . strtoupper($key))
- ->duration(2 * 365 * 24 * 60)
- ->description(__('cookieConsent::cookies.defaults._ga_ID'))
- )
- ->cookie(fn(Cookie $cookie) => $cookie->name('_gid')
- ->duration(24 * 60)
- ->description(__('cookieConsent::cookies.defaults._gid'))
- )
- ->cookie(fn(Cookie $cookie) => $cookie->name('_gat')
- ->duration(1)
- ->description(__('cookieConsent::cookies.defaults._gat'))
- )
+ $this->getGroupCookies(group: $group, name: static::GOOGLE_ANALYTICS, id: $id)
->accepted(fn(Consent $consent) => $consent
->script('')
->script(
@@ -40,6 +47,35 @@ public function google(string $id, bool $anonymizeIp = true): static
);
});
+ return $this;
+ }
+
+ public function gtm(string $id): static
+ {
+ $consentSettings = config('cookieconsent.gtm_consent', [
+ 'ad_user_data',
+ 'ad_personalization',
+ 'ad_storage',
+ 'analytics_storage',
+ ]);
+ $consentSettings = array_fill_keys($consentSettings, 'granted');
+
+ $consentJson = json_encode($consentSettings, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+
+ $this->group(function (CookiesGroup $group) use ($consentJson, $id) {
+ $this->getGroupCookies(group: $group, name: static::GOOGLE_TAG_MANAGER, id: $id)
+ ->accepted(fn(Consent $consent) => $consent
+ ->script('')
+ ->script(
+ ''
+ )
+ ->script(
+ ''
+ )
+ );
+ });
+
+
return $this;
}
}
From 19f948bf5d4e53d063bfd657bc511ccbfbb55c1a Mon Sep 17 00:00:00 2001
From: Debatty-Tom <145542891+Debatty-Tom@users.noreply.github.com>
Date: Thu, 9 Oct 2025 10:58:43 +0200
Subject: [PATCH 3/8] Added default gtm script tag if gtm enable
---
src/CookiesManager.php | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/src/CookiesManager.php b/src/CookiesManager.php
index 58b387c..e3ec37e 100644
--- a/src/CookiesManager.php
+++ b/src/CookiesManager.php
@@ -2,6 +2,7 @@
namespace Whitecube\LaravelCookieConsent;
+use Illuminate\Database\Eloquent\Casts\Json;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie as CookieFacade;
use Symfony\Component\HttpFoundation\Cookie as CookieComponent;
@@ -198,11 +199,41 @@ protected function getConsentedScripts(bool $withDefault): string
protected function getDefaultScriptTag(): string
{
+ $gtmScript = config('cookieconsent.google_tag_manager.id') ? $this->getGTMScript() : null;
+
return '';
+ . '>'
+ . $gtmScript ?? '';
+ }
+
+ /**
+ * Define default Google Tag Manager script tag;
+ */
+ private function getGTMScript()
+ {
+ $defaultSettings = config('cookieconsent.gtm_consent', [
+ 'ad_user_data',
+ 'ad_personalization',
+ 'ad_storage',
+ 'analytics_storage',
+ ]);
+
+ $defaultSettings = array_fill_keys($defaultSettings, 'denied');
+ $defaultSettings['wait_for_update'] = 500;
+
+ $defaultJson = json_encode($defaultSettings, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+
+ return ' ';
}
/**
From 83d69c79910343c138b8443b2f760a555c880e63 Mon Sep 17 00:00:00 2001
From: Debatty-Tom <145542891+Debatty-Tom@users.noreply.github.com>
Date: Fri, 17 Oct 2025 15:57:30 +0200
Subject: [PATCH 4/8] provide the necessary configurations as arguments rather
than in the configuration file
---
config/cookieconsent.php | 12 ------------
src/AnalyticCookiesCategory.php | 15 ++++++---------
src/CookiesManager.php | 9 ++-------
3 files changed, 8 insertions(+), 28 deletions(-)
diff --git a/config/cookieconsent.php b/config/cookieconsent.php
index c1b2af3..6e4ace0 100644
--- a/config/cookieconsent.php
+++ b/config/cookieconsent.php
@@ -85,16 +85,4 @@
'id' => env('GOOGLE_TAG_MANAGER_ID'),
],
- /* Google Tag Manager configuration
- |--------------------------------------------------------------------------
- |
- | These rules will define the data that Google Tag Manager will receive.
- |
- */
- 'gtm_consent' => [
- 'ad_user_data',
- 'ad_personalization',
- 'ad_storage',
- 'analytics_storage',
- ]
];
diff --git a/src/AnalyticCookiesCategory.php b/src/AnalyticCookiesCategory.php
index 80d29da..efa9f9b 100644
--- a/src/AnalyticCookiesCategory.php
+++ b/src/AnalyticCookiesCategory.php
@@ -33,7 +33,7 @@ protected function getGroupCookies($group, $name, $id)
/**
* Define Google Analytics cookies all at once.
*/
- public function google(string $id, bool $anonymizeIp = true): static
+ public function googleAnalytics(string $id, bool $anonymizeIp = true): static
{
$this->group(function (CookiesGroup $group) use ($anonymizeIp, $id) {
$anonymizeIp = $anonymizeIp === true ? 'true' : 'false';
@@ -50,15 +50,12 @@ public function google(string $id, bool $anonymizeIp = true): static
return $this;
}
- public function gtm(string $id): static
+ public function googleTagManager(string $id, $config): static
{
- $consentSettings = config('cookieconsent.gtm_consent', [
- 'ad_user_data',
- 'ad_personalization',
- 'ad_storage',
- 'analytics_storage',
- ]);
- $consentSettings = array_fill_keys($consentSettings, 'granted');
+ app()->instance('cookieconsent.gtm.enabled', true);
+ app()->instance('cookieconsent.gtm.config', $config);
+
+ $consentSettings = array_fill_keys($config, 'granted');
$consentJson = json_encode($consentSettings, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
diff --git a/src/CookiesManager.php b/src/CookiesManager.php
index e3ec37e..e0ffdca 100644
--- a/src/CookiesManager.php
+++ b/src/CookiesManager.php
@@ -199,7 +199,7 @@ protected function getConsentedScripts(bool $withDefault): string
protected function getDefaultScriptTag(): string
{
- $gtmScript = config('cookieconsent.google_tag_manager.id') ? $this->getGTMScript() : null;
+ $gtmScript = app()->has('cookieconsent.gtm.enabled') ? $this->getGTMScript() : null;
return ''
- . $gtmScript ?? '';
+ . '>';
}
/**
* Define default Google Tag Manager script tag;
*/
- private function getGTMScript()
+ private function getGTMScript(): string
{
- $defaultSettings = app('cookieconsent.gtm.config');
+ if (GoogleTagManagerConfig::isEnabled()) {
+ $this->gtmEnabled = true;
+ $this->gtmConfig = GoogleTagManagerConfig::getConfig();
+ }
+
+ if (! $this->gtmEnabled){
+ return '';
+ }
+
+ $defaultSettings = $this->gtmConfig;
$defaultSettings = array_fill_keys($defaultSettings, 'denied');
$defaultSettings['wait_for_update'] = 500;
diff --git a/src/GoogleTagManagerConfig.php b/src/GoogleTagManagerConfig.php
new file mode 100644
index 0000000..c269ae8
--- /dev/null
+++ b/src/GoogleTagManagerConfig.php
@@ -0,0 +1,31 @@
+
Date: Wed, 22 Oct 2025 12:05:29 +0200
Subject: [PATCH 8/8] Added some explanations
---
README.md | 84 ++++++++++++++++++++++++++++++--
stubs/CookiesServiceProvider.php | 7 +--
2 files changed, 83 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 654c72d..713c1eb 100644
--- a/README.md
+++ b/README.md
@@ -109,12 +109,25 @@ class CookiesServiceProvider extends ServiceProvider
->session()
->csrf();
- // Register all Analytics cookies at once using one single shorthand method:
+ // Register all Google Analytics cookies at once using one single shorthand method:
+ // Don't forget to change the id an anonymizeIp to point to the good location
Cookies::analytics()
- ->google(
- id: config('cookieconsent.google_analytics.id')
- anonymizeIp: config('cookieconsent.google_analytics.anonymize_ip')
- );
+ ->googleAnalytics(
+ id: config('your_config.google_analytics.id'),
+ anonymizeIp: config('your_config.google_analytics.anonymize_ip')
+ );
+
+ // Using Google Tag Manager? Use this method instead of the Google Analytics one;
+ Cookies::analytics()
+ ->googleTagManager(
+ id: config('your_config.google_tag_manager.id'),
+ config: [
+ 'ad_user_data',
+ 'ad_personalization',
+ 'ad_storage',
+ 'analytics_storage',
+ ]
+ );
// Register custom cookies under the pre-existing "optional" category:
Cookies::optional()
@@ -129,6 +142,8 @@ class CookiesServiceProvider extends ServiceProvider
More details on the available [cookie registration](#registering-cookies) methods below.
+More details on the [Google Analytics and Google Tag Manager](#analytics-cookies-custom-methods) methods below.
+
Then, let's add consent scripts and modals to the application's views using the following blade directives:
- `@cookieconsentscripts`: used to add the package's default JavaScript and any third-party scripts you need to get the end-user's consent for.
@@ -413,6 +428,65 @@ Most of the displayed strings are defined in the `cookieConsent::cookies` transl
If not already published, you can edit or fill the translation files using `php artisan vendor:publish --tag=laravel-cookie-consent-lang`, this will copy our translation files to your app's `vendor/cookieConsent` "lang" path.
+## Analytics cookies custom methods
+
+### Google Analytics (GA)
+
+Register all Google Analytics cookies at once using the shorthand method:
+
+```php
+Cookies::analytics()
+ ->googleAnalytics(
+ id: config('services.google_analytics.id'),
+ anonymizeIp: config('services.google_analytics.anonymize_ip', true)
+ );
+```
+
+### Google Tag Manager (GTM)
+
+For Google Tag Manager with consent mode v2, use this method instead:
+
+```php
+Cookies::analytics()
+ ->googleTagManager(
+ id: id: config('services.google_tag_manager.id'), // Your Google Tag Manager Container ID
+ config: [
+ 'ad_storage', // Enables storage for advertising
+ 'ad_user_data', // Enables sending user data for advertising
+ 'ad_personalization', // Enables personalized advertising
+ 'analytics_storage', // Enables storage for analytics
+ ]
+ );
+```
+
+You can find all the available consent types on [the Google Tag Manager documentation](https://support.google.com/tagmanager/answer/10718549?hl=en)
+
+**Config file example (`config/services.php`):**
+```php
+return [
+ 'google_analytics' => [
+ 'id' => env('GOOGLE_ANALYTICS_ID'),
+ 'anonymize_ip' => env('GOOGLE_ANALYTICS_ANONYMIZE_IP', true),
+ ],
+
+ 'google_tag_manager' => [
+ 'id' => env('GOOGLE_TAG_MANAGER_ID'),
+ ],
+];
+```
+
+**Environment variables (`.env`):**
+```env
+GOOGLE_ANALYTICS_ID=G-XXXXXXXXXX
+GOOGLE_ANALYTICS_ANONYMIZE_IP=true
+
+GOOGLE_TAG_MANAGER_ID=GTM-XXXXXXX
+```
+
+**Note:** When using Google Tag Manager, the consent mode is automatically configured. Users must accept the analytics cookies before GTM scripts are loaded. The default consent state is set to "denied" for all specified consent types until the user gives explicit consent.
+
+> **Important:** Don't use both `googleAnalytics()` and `googleTagManager()` methods together. Choose one based on your tracking setup.
+
## A few useful tips
> **Disclaimer**: We are not lawyers. Always check with your legal partners which rules may apply to your project.
diff --git a/stubs/CookiesServiceProvider.php b/stubs/CookiesServiceProvider.php
index 4542fc4..f4cc966 100644
--- a/stubs/CookiesServiceProvider.php
+++ b/stubs/CookiesServiceProvider.php
@@ -18,15 +18,16 @@ protected function registerCookies(): void
->csrf();
// Register all Analytics cookies at once using one single shorthand method:
+ // Don't forget to change the config location to match your config file
// Cookies::analytics()
// ->googleAnalytics(
- // id: config('cookieconsent.google_analytics.id'),
- // anonymizeIp: config('cookieconsent.google_analytics.anonymize_ip')
+ // id: config('your_config.google_analytics.id'),
+ // anonymizeIp: config('your_config.google_analytics.anonymize_ip')
// );
// Cookies::analytics()
// ->googleTagManager(
- // id: config('cookieconsent.google_tag_manager.id'),
+ // id: config('your_config.google_tag_manager.id'),
// config: [
// 'ad_user_data',
// 'ad_personalization',