├── .editorconfig ├── .gitignore ├── LICENSE.md ├── README.md ├── composer.json ├── composer.lock ├── config └── livewire-cookie-consent.php ├── docs ├── GTM-Github_v16_livewire-cookie-consent.json └── img │ ├── livewire-cookie-consent-modal1.jpg │ └── livewire-cookie-consent-modal2.jpg ├── public └── LaravelLogo.svg ├── resources ├── lang │ ├── de │ │ └── texts.php │ ├── en │ │ └── texts.php │ └── es │ │ └── texts.php └── views │ ├── cookie-consent-edit.blade.php │ ├── cookie-consent-modal.blade.php │ └── cookieconsent.blade.php └── src ├── CookieConsentModalService.php ├── CookieConsentModalServiceProvider.php ├── Livewire ├── CookieConsentEdit.php └── CookieConsentModal.php └── views └── cookieconsent.blade.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = false 9 | max_line_length = 120 10 | tab_width = 4 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Martinschenk mschenk.pda@gmail.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ⚠️ Maintenance Notice 2 | 3 | **This package is no longer actively maintained.** This package was built for Laravel 9/10 with Jetstream and Livewire v2 (created in late 2022). While it may continue to work with current Laravel/Livewire versions, I'm not providing regular updates or bug fixes. Feel free to fork the repository if you need ongoing maintenance or want to contribute improvements. 4 | 5 | **👆 Consider upgrading to the [new lightweight Laravel Cookie Consent Plugin](https://github.com/martinschenk/laravel-cookie-consent) instead!** 6 | 7 | # 🆕 **Alternative: Simple GDPR Cookie Consent Available!** 8 | 9 | **🚀 [Try the lightweight Laravel Cookie Consent Plugin](https://github.com/martinschenk/laravel-cookie-consent)** 10 | 11 | Looking for something simpler? This alternative plugin offers: 12 | - ✅ **Framework-independent** - no Laravel or JavaScript framework dependencies 13 | - ✅ **Ultra-lightweight** - minimal footprint, maximum performance 14 | - ✅ **GDPR-compliant out-of-the-box** - automatically blocks Google Analytics until consent 15 | - ✅ **Dead simple setup** - just add your Google Analytics ID and you're done 16 | - ✅ **User-friendly modals** - clean, responsive consent interface 17 | - ✅ **Persistent user control** - footer link allows users to change preferences anytime 18 | 19 | **Perfect for projects that need** straightforward cookie consent without complex dependencies or extensive configuration. Ideal if you want to get GDPR compliance up and running in minutes. 20 | 21 | --- 22 | 23 | # Laravel Livewire Cookie-Consent Modal 24 | 25 | [](https://packagist.org/packages/martinschenk/livewire-cookie-consent) 26 | [](https://packagist.org/packages/martinschenk/livewire-cookie-consent) 27 | 28 | With [this package](https://github.com/martinschenk/livewire-cookie-consent) there will be set no (Google Marketing & Analytics) Cookies on your website, until the user has accepted the Cookie Policy. (Except essential and funtionality cookies). All of this, because of the crazy EU Cookie Law. 29 | 30 | 31 | 32 |  33 |  34 | 35 | 36 | Livewire Cookie Consent is a Livewire component that provides Opt-In Cookie Modals. The user can choose between 37 | - Essential and functional cookies 38 | - Analytical cookies 39 | - Marketing cookies 40 | 41 | Special: 42 | - No Analytical or Marketing cookies are set before the Opt-In decision of the user (European laws). 43 | - User can open the modal with link in page-footer to reconfigure his cookie consent selections. 44 | - You can connect this component to Google Tag Manager if you want to. GTM example Script is included. 45 | - You can add in your Google Tag Manager triggers for every other Cookie, you wish to control. 46 | 47 | ## Requirements 48 | 49 | - Laravel 9/10 50 | - Laravel Jetstream with Livewire v2 51 | - PHP 8.0+ 52 | 53 | Jetstream should only be installed into new Laravel applications. Attempting to install Jetstream into an existing Laravel application will result in unexpected behavior and issues 54 | 55 | ## Installation 56 | 57 | ### If you haven't installed Jetstream and Livewire 58 | 59 | ``` bash 60 | composer require laravel/jetstream 61 | 62 | php artisan jetstream:install livewire 63 | ``` 64 | ### And now install the package 65 | 66 | ``` bash 67 | composer require martinschenk/livewire-cookie-consent 68 | ``` 69 | Register the package in /config/app.php 70 | 71 | ```php 72 | return [ 73 | /* 74 | * Application Service Providers... 75 | */ 76 | 77 | App\Providers\AppServiceProvider::class, 78 | ... 79 | Martinschenk\LivewireCookieConsent\CookieConsentModalServiceProvider::class, 80 | 81 | ]; 82 | ``` 83 | 84 | ## Finalizing The Installation 85 | After installing Jetstream, you should install and build your NPM dependencies and migrate your database: 86 | 87 | ``` bash 88 | npm install 89 | npm run build 90 | php artisan migrate 91 | ``` 92 | 93 | 94 | ## Include Livewire and vite directives 95 | Include this into your welcome.blade.php, landing page or any other base template you use. 96 | ```html 97 | 98 |
99 | ... 100 | @livewireStyles 101 | @vite(['resources/css/app.css', 'resources/js/app.js']) 102 | 103 | 104 | ... 105 | @livewireScripts 106 | @livewire('livewire-ui-modal') 107 | @include('livewire-cookie-consent::cookieconsent') 108 | 109 | 110 | ``` 111 | 112 | ## Include link 113 | Normaly in the footer of your web-page, include this link. It will open the cookie modal to change preferences. 114 | ```html 115 | 117 | {{ __('Cookie Config') }} 118 | 119 | ``` 120 | 121 | ## Publish the views and logo 122 | The design is done with Tailwind. You can edit and adapt the files. 123 | You will find the views in resources/views/vendor/livewire-cookie-consent 124 | ```bash 125 | php artisan vendor:publish --provider="Martinschenk\LivewireCookieConsent\CookieConsentModalServiceProvider" --tag="views" 126 | ``` 127 | 128 | 129 | ## Now it should work 130 | Do just 131 | ```bash 132 | php artisan optimize:clear 133 | npm run dev 134 | ``` 135 | and you should see popup the modal if you reload your webpage. 136 | 137 | ## Publish the rest if you want to 138 | ### Dialog texts and languages 139 | 140 | If you want to modify the text shown in the dialog you can publish the lang-files with this command: 141 | 142 | ```bash 143 | php artisan vendor:publish --provider="Martinschenk\LivewireCookieConsent\CookieConsentModalServiceProvider" --tag="lang" 144 | ``` 145 | This will publish the f.e. english language file to lang/vendor/livewire-cookie-consent/en/texts.php . 146 | ```php 147 | 148 | return [ 149 | 'alert_accept' => 'Accept all cookies', 150 | 'alert_essentials_only' => 'Accept only necessary cookies', 151 | 'alert_settings' => 'Adjust your preferences', 152 | ... 153 | ]; 154 | 155 | 156 | ``` 157 | 158 | ### Config file 159 | Be careful changing the config values, because the Google Tag Manager is using them. Only change them if you know what you do. 160 | ```bash 161 | php artisan vendor:publish --provider="Martinschenk\LivewireCookieConsent\CookieConsentModalServiceProvider" --tag="config" 162 | ``` 163 | 164 | This is the content of the published config-file. You'll find it in /config/livewire-cookie-consent.php 165 | 166 | 167 | ```php 168 | 169 | return 170 | 171 | 'cookie_name' => 'cookie-consent', 172 | 173 | 'cookie_value_analytics' => '2', 174 | 'cookie_value_marketing' => '3', 175 | 'cookie_value_both' => 'true', 176 | 'cookie_value_none' => 'false', 177 | 178 | 'consent_cookie_lifetime' => 60 * 24 * 365, 179 | 'refuse_cookie_lifetime' => 60 * 24 * 30, 180 | 181 | ]; 182 | 183 | 184 | ``` 185 | 186 | 187 | ## Configure Google Tag Manager 188 | If you want to use Google Tag Manager, you will find an example Container script for configuration of GTM [here](./docs/GTM-Github_v16_livewire-cookie-consent.json) 189 | 190 | [Example Container for GTM:](./docs/GTM-Github_v16_livewire-cookie-consent.json) 191 | ```json 192 | { 193 | "exportFormatVersion": 2, 194 | "exportTime": "2022-11-25 20:49:55", 195 | "containerVersion": { 196 | "path": "accounts/6060538801/containers/95560929/versions/16", 197 | "accountId": "6060538801", 198 | "containerId": "95560929", 199 | "containerVersionId": "16", 200 | "name": "cookie consent v1.0", 201 | "container": { 202 | "path": "accounts/6060538801/containers/95560929", 203 | "accountId": "6060538801", 204 | "containerId": "95560929", 205 | "name": "www.vissit.io", 206 | "publicId": "GTM-YOUR-CODE", 207 | 208 | ``` 209 | 210 | You can import or merge this GTM Container into your GTM account. Here you can find the [GTM Documentation](https://support.google.com/tagmanager/answer/6106997?hl=en-GB) for importing a Container. Its possible that you have to change the GTM-Code in the GTM Container to your own GTM-Code. 211 | 212 | Once configured your Google Tag Manager, you have to insert the Google Tag Manager Code in the HEAD section of your website this way (between @livewireStyles and @vite...): 213 | 214 | ```html 215 | @livewireStyles 216 | HERE THE GOOGLE TAG MANAGER CODE 217 | @vite(['resources/css/app.css', 'resources/js/app.js']) 218 | ``` 219 | 220 | Example: 221 | 222 | ```html 223 | 224 | 225 | ... 226 | @livewireStyles 227 | 228 | 229 | 232 | 233 | 238 | 239 | 240 | @vite(['resources/css/app.css', 'resources/js/app.js']) 241 | 242 | ``` 243 | Replace GTM-YOURKEY with your Google Tag Manager Key. 244 | 245 | ## Security 246 | 247 | If you discover any security related issues, please email [mschenk.pda@gmail.com](mailto:mschenk.pda@gmail.com) instead of using the issue tracker. 248 | 249 | ## Credits 250 | This package is based on the one from spatie: https://github.com/spatie/laravel-cookie-consent and on statikbe: https://github.com/statikbe/laravel-cookie-consent 251 | 252 | ## License 253 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 254 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "martinschenk/livewire-cookie-consent", 3 | "description": "livewire cookie consent modals with laravel livewire", 4 | "keywords": ["laravel", "livewire", "cookie", "consent", "cookie-consent", "modal"], 5 | "homepage": "https://github.com/martinschenk/livewire-cookie-consent", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Martin Schenk", 10 | "email": "mschenk.pda@gmail.com", 11 | "homepage": "https://www.martin-schenk.es", 12 | "role": "Developer " 13 | } 14 | ], 15 | "require": { 16 | "php": "^8.0", 17 | "livewire/livewire": "^2.0", 18 | "wire-elements/modal": "^1.0" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "Martinschenk\\LivewireCookieConsent\\": "src/" 23 | } 24 | }, 25 | "extra": { 26 | "laravel": { 27 | "providers": [ 28 | "Martinschenk\\LivewireCookieConsent\\CookieConsentModalServiceProvider" 29 | ] 30 | } 31 | }, 32 | "minimum-stability": "dev", 33 | "prefer-stable": true 34 | } 35 | -------------------------------------------------------------------------------- /config/livewire-cookie-consent.php: -------------------------------------------------------------------------------- 1 | 'cookie-consent', 4 | 5 | 'cookie_value_analytics' => '2', 6 | 'cookie_value_marketing' => '3', 7 | 'cookie_value_both' => 'true', 8 | 'cookie_value_none' => 'false', 9 | 10 | 'consent_cookie_lifetime' => 60 * 24 * 365, 11 | 'refuse_cookie_lifetime' => 60 * 24 * 30, 12 | 13 | 'ignored_paths' => [], 14 | 15 | 'policy_url_en' => env('COOKIE_POLICY_URL_EN', '/politica-cookies'), 16 | 'policy_url_de' => env('COOKIE_POLICY_URL_DE', '/cookie-richtlinie'), 17 | 'policy_url_es' => env('COOKIE_POLICY_URL_ES', '/politica-cookies'), 18 | ]; 19 | -------------------------------------------------------------------------------- /docs/GTM-Github_v16_livewire-cookie-consent.json: -------------------------------------------------------------------------------- 1 | { 2 | "exportFormatVersion": 2, 3 | "exportTime": "2022-11-25 20:49:55", 4 | "containerVersion": { 5 | "path": "accounts/6060538801/containers/95560929/versions/16", 6 | "accountId": "6060538801", 7 | "containerId": "95560929", 8 | "containerVersionId": "16", 9 | "name": "cookie consent v1.0", 10 | "container": { 11 | "path": "accounts/6060538801/containers/95560929", 12 | "accountId": "6060538801", 13 | "containerId": "95560929", 14 | "name": "www.vissit.io", 15 | "publicId": "GTM-YOUR-CODE", 16 | "usageContext": [ 17 | "WEB" 18 | ], 19 | "fingerprint": "1666364380153", 20 | "tagManagerUrl": "https://tagmanager.google.com/#/container/accounts/6060538801/containers/95560929/workspaces?apiLink=container", 21 | "features": { 22 | "supportUserPermissions": true, 23 | "supportEnvironments": true, 24 | "supportWorkspaces": true, 25 | "supportGtagConfigs": false, 26 | "supportBuiltInVariables": true, 27 | "supportClients": false, 28 | "supportFolders": true, 29 | "supportTags": true, 30 | "supportTemplates": true, 31 | "supportTriggers": true, 32 | "supportVariables": true, 33 | "supportVersions": true, 34 | "supportZones": true 35 | }, 36 | "tagIds": [ 37 | "GTM-YOUR-CODE" 38 | ] 39 | }, 40 | "tag": [ 41 | { 42 | "accountId": "6060538801", 43 | "containerId": "95560929", 44 | "tagId": "25", 45 | "name": "Consent Mode update", 46 | "type": "cvt_95560929_17", 47 | "parameter": [ 48 | { 49 | "type": "TEMPLATE", 50 | "key": "update_ad_storage", 51 | "value": "{{bool-ads}}" 52 | }, 53 | { 54 | "type": "TEMPLATE", 55 | "key": "update_functionality_storage", 56 | "value": "granted" 57 | }, 58 | { 59 | "type": "BOOLEAN", 60 | "key": "ads_data_redaction", 61 | "value": "false" 62 | }, 63 | { 64 | "type": "TEMPLATE", 65 | "key": "update_security_storage", 66 | "value": "granted" 67 | }, 68 | { 69 | "type": "BOOLEAN", 70 | "key": "sendDataLayer", 71 | "value": "false" 72 | }, 73 | { 74 | "type": "TEMPLATE", 75 | "key": "update_analytics_storage", 76 | "value": "{{bool-analytics}}" 77 | }, 78 | { 79 | "type": "TEMPLATE", 80 | "key": "update_personalization_storage", 81 | "value": "granted" 82 | }, 83 | { 84 | "type": "TEMPLATE", 85 | "key": "command", 86 | "value": "update" 87 | }, 88 | { 89 | "type": "BOOLEAN", 90 | "key": "url_passthrough", 91 | "value": "false" 92 | }, 93 | { 94 | "type": "BOOLEAN", 95 | "key": "sendGtag", 96 | "value": "false" 97 | } 98 | ], 99 | "fingerprint": "1669404876127", 100 | "firingTriggerId": [ 101 | "2147479573", 102 | "22", 103 | "38" 104 | ], 105 | "tagFiringOption": "ONCE_PER_EVENT", 106 | "monitoringMetadata": { 107 | "type": "MAP" 108 | }, 109 | "consentSettings": { 110 | "consentStatus": "NOT_SET" 111 | } 112 | }, 113 | { 114 | "accountId": "6060538801", 115 | "containerId": "95560929", 116 | "tagId": "33", 117 | "name": "Google Analytics GA4 Configuration", 118 | "type": "gaawc", 119 | "parameter": [ 120 | { 121 | "type": "BOOLEAN", 122 | "key": "sendPageView", 123 | "value": "true" 124 | }, 125 | { 126 | "type": "BOOLEAN", 127 | "key": "enableSendToServerContainer", 128 | "value": "false" 129 | }, 130 | { 131 | "type": "TEMPLATE", 132 | "key": "measurementId", 133 | "value": "G-4N6QE89SKJ" 134 | } 135 | ], 136 | "fingerprint": "1669404931225", 137 | "firingTriggerId": [ 138 | "2147479553", 139 | "39" 140 | ], 141 | "tagFiringOption": "ONCE_PER_EVENT", 142 | "monitoringMetadata": { 143 | "type": "MAP" 144 | }, 145 | "consentSettings": { 146 | "consentStatus": "NEEDED", 147 | "consentType": { 148 | "type": "LIST", 149 | "list": [ 150 | { 151 | "type": "TEMPLATE", 152 | "value": "analytics_storage" 153 | } 154 | ] 155 | } 156 | } 157 | }, 158 | { 159 | "accountId": "6060538801", 160 | "containerId": "95560929", 161 | "tagId": "35", 162 | "name": "Google Analytics Universal Analytics", 163 | "type": "ua", 164 | "parameter": [ 165 | { 166 | "type": "BOOLEAN", 167 | "key": "overrideGaSettings", 168 | "value": "false" 169 | }, 170 | { 171 | "type": "TEMPLATE", 172 | "key": "trackType", 173 | "value": "TRACK_PAGEVIEW" 174 | }, 175 | { 176 | "type": "TEMPLATE", 177 | "key": "gaSettings", 178 | "value": "{{Google Analytics Settings}}" 179 | } 180 | ], 181 | "fingerprint": "1669404931224", 182 | "firingTriggerId": [ 183 | "2147479553", 184 | "39" 185 | ], 186 | "tagFiringOption": "ONCE_PER_EVENT", 187 | "monitoringMetadata": { 188 | "type": "MAP" 189 | }, 190 | "consentSettings": { 191 | "consentStatus": "NEEDED", 192 | "consentType": { 193 | "type": "LIST", 194 | "list": [ 195 | { 196 | "type": "TEMPLATE", 197 | "value": "analytics_storage" 198 | } 199 | ] 200 | } 201 | } 202 | }, 203 | { 204 | "accountId": "6060538801", 205 | "containerId": "95560929", 206 | "tagId": "36", 207 | "name": "cHTML - dataLayer push Consent", 208 | "type": "html", 209 | "parameter": [ 210 | { 211 | "type": "TEMPLATE", 212 | "key": "html", 213 | "value": " " 214 | }, 215 | { 216 | "type": "BOOLEAN", 217 | "key": "supportDocumentWrite", 218 | "value": "false" 219 | } 220 | ], 221 | "fingerprint": "1669404312987", 222 | "firingTriggerId": [ 223 | "37" 224 | ], 225 | "tagFiringOption": "ONCE_PER_EVENT", 226 | "monitoringMetadata": { 227 | "type": "MAP" 228 | }, 229 | "consentSettings": { 230 | "consentStatus": "NOT_SET" 231 | } 232 | } 233 | ], 234 | "trigger": [ 235 | { 236 | "accountId": "6060538801", 237 | "containerId": "95560929", 238 | "triggerId": "22", 239 | "name": "cookie_consent", 240 | "type": "CUSTOM_EVENT", 241 | "customEventFilter": [ 242 | { 243 | "type": "EQUALS", 244 | "parameter": [ 245 | { 246 | "type": "TEMPLATE", 247 | "key": "arg0", 248 | "value": "{{_event}}" 249 | }, 250 | { 251 | "type": "TEMPLATE", 252 | "key": "arg1", 253 | "value": "cookie-consent" 254 | } 255 | ] 256 | } 257 | ], 258 | "fingerprint": "1669054852865" 259 | }, 260 | { 261 | "accountId": "6060538801", 262 | "containerId": "95560929", 263 | "triggerId": "37", 264 | "name": "click - consent choice", 265 | "type": "CLICK", 266 | "filter": [ 267 | { 268 | "type": "CONTAINS", 269 | "parameter": [ 270 | { 271 | "type": "TEMPLATE", 272 | "key": "arg0", 273 | "value": "{{Click Classes}}" 274 | }, 275 | { 276 | "type": "TEMPLATE", 277 | "key": "arg1", 278 | "value": "gtm-cookie-button" 279 | } 280 | ] 281 | } 282 | ], 283 | "fingerprint": "1669404149988" 284 | }, 285 | { 286 | "accountId": "6060538801", 287 | "containerId": "95560929", 288 | "triggerId": "38", 289 | "name": "custom - consent choice", 290 | "type": "CUSTOM_EVENT", 291 | "customEventFilter": [ 292 | { 293 | "type": "EQUALS", 294 | "parameter": [ 295 | { 296 | "type": "TEMPLATE", 297 | "key": "arg0", 298 | "value": "{{_event}}" 299 | }, 300 | { 301 | "type": "TEMPLATE", 302 | "key": "arg1", 303 | "value": "consentChoice" 304 | } 305 | ] 306 | } 307 | ], 308 | "fingerprint": "1669404820786" 309 | }, 310 | { 311 | "accountId": "6060538801", 312 | "containerId": "95560929", 313 | "triggerId": "39", 314 | "name": "custom - consent updated", 315 | "type": "CUSTOM_EVENT", 316 | "customEventFilter": [ 317 | { 318 | "type": "EQUALS", 319 | "parameter": [ 320 | { 321 | "type": "TEMPLATE", 322 | "key": "arg0", 323 | "value": "{{_event}}" 324 | }, 325 | { 326 | "type": "TEMPLATE", 327 | "key": "arg1", 328 | "value": "consentUpdated" 329 | } 330 | ] 331 | } 332 | ], 333 | "fingerprint": "1669404620912" 334 | } 335 | ], 336 | "variable": [ 337 | { 338 | "accountId": "6060538801", 339 | "containerId": "95560929", 340 | "variableId": "23", 341 | "name": "cookie-consent-cookie", 342 | "type": "k", 343 | "parameter": [ 344 | { 345 | "type": "BOOLEAN", 346 | "key": "decodeCookie", 347 | "value": "true" 348 | }, 349 | { 350 | "type": "TEMPLATE", 351 | "key": "name", 352 | "value": "cookie-consent" 353 | } 354 | ], 355 | "fingerprint": "1668956195326", 356 | "formatValue": {} 357 | }, 358 | { 359 | "accountId": "6060538801", 360 | "containerId": "95560929", 361 | "variableId": "24", 362 | "name": "Consent State", 363 | "type": "cvt_95560929_14", 364 | "parameter": [ 365 | { 366 | "type": "TEMPLATE", 367 | "key": "selectTarget", 368 | "value": "all" 369 | } 370 | ], 371 | "fingerprint": "1668956308751", 372 | "formatValue": {} 373 | }, 374 | { 375 | "accountId": "6060538801", 376 | "containerId": "95560929", 377 | "variableId": "26", 378 | "name": "bool-analytics", 379 | "type": "jsm", 380 | "parameter": [ 381 | { 382 | "type": "TEMPLATE", 383 | "key": "javascript", 384 | "value": "function(){\nvar coo = {{cookie-consent-cookie}};\nif(coo == '2' || coo == 'true'){\n return 'granted';\n}else{\n return 'denied';\n}\n}\n\n " 385 | } 386 | ], 387 | "fingerprint": "1669055657147", 388 | "formatValue": {} 389 | }, 390 | { 391 | "accountId": "6060538801", 392 | "containerId": "95560929", 393 | "variableId": "27", 394 | "name": "bool-ads", 395 | "type": "jsm", 396 | "parameter": [ 397 | { 398 | "type": "TEMPLATE", 399 | "key": "javascript", 400 | "value": "function(){\nvar coo = {{cookie-consent-cookie}};\nif(coo == '3' || coo == 'true'){\n return 'granted';\n}else{\n return 'denied';\n}\n}\n\n " 401 | } 402 | ], 403 | "fingerprint": "1669055528183", 404 | "formatValue": {} 405 | }, 406 | { 407 | "accountId": "6060538801", 408 | "containerId": "95560929", 409 | "variableId": "34", 410 | "name": "Google Analytics Settings", 411 | "type": "gas", 412 | "parameter": [ 413 | { 414 | "type": "TEMPLATE", 415 | "key": "cookieDomain", 416 | "value": "auto" 417 | }, 418 | { 419 | "type": "BOOLEAN", 420 | "key": "doubleClick", 421 | "value": "false" 422 | }, 423 | { 424 | "type": "BOOLEAN", 425 | "key": "setTrackerName", 426 | "value": "false" 427 | }, 428 | { 429 | "type": "BOOLEAN", 430 | "key": "useDebugVersion", 431 | "value": "false" 432 | }, 433 | { 434 | "type": "BOOLEAN", 435 | "key": "useHashAutoLink", 436 | "value": "false" 437 | }, 438 | { 439 | "type": "BOOLEAN", 440 | "key": "decorateFormsAutoLink", 441 | "value": "false" 442 | }, 443 | { 444 | "type": "BOOLEAN", 445 | "key": "enableLinkId", 446 | "value": "false" 447 | }, 448 | { 449 | "type": "BOOLEAN", 450 | "key": "enableEcommerce", 451 | "value": "false" 452 | }, 453 | { 454 | "type": "TEMPLATE", 455 | "key": "trackingId", 456 | "value": "UA-150942571-1" 457 | } 458 | ], 459 | "fingerprint": "1669393962223" 460 | } 461 | ], 462 | "builtInVariable": [ 463 | { 464 | "accountId": "6060538801", 465 | "containerId": "95560929", 466 | "type": "PAGE_URL", 467 | "name": "Page URL" 468 | }, 469 | { 470 | "accountId": "6060538801", 471 | "containerId": "95560929", 472 | "type": "PAGE_HOSTNAME", 473 | "name": "Page Hostname" 474 | }, 475 | { 476 | "accountId": "6060538801", 477 | "containerId": "95560929", 478 | "type": "PAGE_PATH", 479 | "name": "Page Path" 480 | }, 481 | { 482 | "accountId": "6060538801", 483 | "containerId": "95560929", 484 | "type": "REFERRER", 485 | "name": "Referrer" 486 | }, 487 | { 488 | "accountId": "6060538801", 489 | "containerId": "95560929", 490 | "type": "EVENT", 491 | "name": "Event" 492 | }, 493 | { 494 | "accountId": "6060538801", 495 | "containerId": "95560929", 496 | "type": "CLICK_CLASSES", 497 | "name": "Click Classes" 498 | } 499 | ], 500 | "fingerprint": "1669406213183", 501 | "tagManagerUrl": "https://tagmanager.google.com/#/versions/accounts/6060538801/containers/95560929/versions/16?apiLink=version", 502 | "customTemplate": [ 503 | { 504 | "accountId": "6060538801", 505 | "containerId": "95560929", 506 | "templateId": "14", 507 | "name": "GTM Consent State", 508 | "fingerprint": "1668618993051", 509 | "templateData": "___TERMS_OF_SERVICE___\n\nBy creating or modifying this file you agree to Google Tag Manager's Community\nTemplate Gallery Developer Terms of Service available at\nhttps://developers.google.com/tag-manager/gallery-tos (or such other URL as\nGoogle may provide), as modified from time to time.\n\n\n___INFO___\n\n{\n \"type\": \"MACRO\",\n \"id\": \"cvt_temp_public_id\",\n \"version\": 1,\n \"securityGroups\": [],\n \"displayName\": \"GTM Consent State\",\n \"categories\": [\n \"UTILITY\"\n ],\n \"description\": \"Get the status of each type of Consent Mode implemented in Google Tag Manager.\",\n \"containerContexts\": [\n \"WEB\"\n ],\n \"brand\": {\n \"displayName\": \"Ayudante\",\n \"id\": \"github.com_Ayudante\"\n }\n}\n\n\n___TEMPLATE_PARAMETERS___\n\n[\n {\n \"type\": \"RADIO\",\n \"name\": \"selectTarget\",\n \"radioItems\": [\n {\n \"value\": \"all\",\n \"displayValue\": \"All types\"\n },\n {\n \"value\": \"any\",\n \"displayValue\": \"Any type\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"all\",\n \"help\": \"Select the name of the Consent Type you want to retrieve.\\u003cbr\\u003e\\nIf you select \\\"\\u003cb\\u003eAll types\\u003c/b\\u003e\\\", you will get the status of the five types provided by default as an \\u003cb\\u003eobject\\u003c/b\\u003e.\\u003cbr\\u003e\\nif you select \\u003cb\\u003e\\\"Any type\\\"\\u003c/b\\u003e, you will get the value of the type as \\u003cb\\u003etrue/false\\u003c/b\\u003e.\",\n \"displayName\": \"Get type\"\n },\n {\n \"type\": \"SELECT\",\n \"name\": \"getType\",\n \"macrosInSelect\": false,\n \"selectItems\": [\n {\n \"value\": \"ad\",\n \"displayValue\": \"ad_storage\"\n },\n {\n \"value\": \"analytics\",\n \"displayValue\": \"analytics_storage\"\n },\n {\n \"value\": \"functional\",\n \"displayValue\": \"functional_storage\"\n },\n {\n \"value\": \"personalization\",\n \"displayValue\": \"personalization_storage\"\n },\n {\n \"value\": \"security\",\n \"displayValue\": \"security_storage\"\n },\n {\n \"value\": \"custom\",\n \"displayValue\": \"\"\n }\n ],\n \"simpleValueType\": true,\n \"alwaysInSummary\": true,\n \"help\": \"If you want to get a type that is not provided by default, select the blank box and enter the name of the type you want to get.\",\n \"defaultValue\": \"ad\",\n \"enablingConditions\": [\n {\n \"paramName\": \"selectTarget\",\n \"paramValue\": \"all\",\n \"type\": \"NOT_EQUALS\"\n }\n ],\n \"displayName\": \"Type name\"\n },\n {\n \"type\": \"TEXT\",\n \"name\": \"customName\",\n \"displayName\": \"\",\n \"simpleValueType\": true,\n \"enablingConditions\": [\n {\n \"paramName\": \"getType\",\n \"paramValue\": \"custom\",\n \"type\": \"EQUALS\"\n }\n ],\n \"valueValidators\": [\n {\n \"type\": \"NON_EMPTY\"\n }\n ],\n \"notSetText\": \"[Required value.]\"\n },\n {\n \"type\": \"LABEL\",\n \"name\": \"customNote\",\n \"displayName\": \"\\u003cb\\u003eNote\\u003c/b\\u003e: If you want to get a custom type, you need to add the name of the type you want to get to the \\u003cb\\u003epermissions\\u003c/b\\u003e of the variable template with read permissions.\\u003cbr\\u003e\\nIf the permission is not set, the value of this variable will be undefined.\",\n \"enablingConditions\": [\n {\n \"paramName\": \"getType\",\n \"paramValue\": \"custom\",\n \"type\": \"EQUALS\"\n }\n ]\n }\n]\n\n\n___SANDBOXED_JS_FOR_WEB_TEMPLATE___\n\n// 初期設定\nconst queryPermission = require('queryPermission');\nconst isConsentGranted = require('isConsentGranted');\nconst getTypeName = {\n\t'ad': 'ad_storage',\n\t'analytics': 'analytics_storage',\n\t'functional': 'functional_storage',\n\t'personalization': 'personalization_storage',\n\t'security': 'security_storage',\n\t'custom': data.customName\n};\n\n// 取得処理\nswitch(data.selectTarget){\n\tcase 'all':\n\t\tif(queryPermission('access_consent', 'ad_storage', 'read') && queryPermission('access_consent', 'analytics_storage', 'read') && queryPermission('access_consent', 'functional_storage', 'read') && queryPermission('access_consent', 'personalization_storage', 'read') && queryPermission('access_consent', 'security_storage', 'read')){\n\t\t\treturn {\n\t\t\t\tad_storage: isConsentGranted('ad_storage'),\n\t\t\t\tanalytics_storage: isConsentGranted('analytics_storage'),\n\t\t\t\tfunctional_storage: isConsentGranted('functional_storage'),\n\t\t\t\tpersonalization_storage: isConsentGranted('personalization_storage'),\n\t\t\t\tsecurity_storage: isConsentGranted('security_storage')\n\t\t\t};\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tif(queryPermission('access_consent', getTypeName[data.getType], 'read')) return isConsentGranted(getTypeName[data.getType]);\n}\n\n// 例外処理\nreturn undefined;\n\n\n___WEB_PERMISSIONS___\n\n[\n {\n \"instance\": {\n \"key\": {\n \"publicId\": \"access_consent\",\n \"versionId\": \"1\"\n },\n \"param\": [\n {\n \"key\": \"consentTypes\",\n \"value\": {\n \"type\": 2,\n \"listItem\": [\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"ad_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": false\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"analytics_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": false\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"functional_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": false\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"personalization_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": false\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"security_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": false\n }\n ]\n }\n ]\n }\n }\n ]\n },\n \"clientAnnotations\": {\n \"isEditedByUser\": true\n },\n \"isRequired\": true\n }\n]\n\n\n___TESTS___\n\nscenarios:\n- name: all\n code: |-\n const mockData = {\n // Mocked field values\n selectTarget: 'all'\n };\n\n // Call runCode to run the template's code.\n let variableResult = runCode(mockData);\n\n // Verify that the variable returns a result.\n assertThat(variableResult).isNotEqualTo(undefined);\n- name: ad\n code: |-\n const mockData = {\n // Mocked field values\n selectTarget: 'any',\n getType: 'ad'\n };\n\n // Call runCode to run the template's code.\n let variableResult = runCode(mockData);\n\n // Verify that the variable returns a result.\n assertThat(variableResult).isNotEqualTo(undefined);\n- name: analytics\n code: |-\n const mockData = {\n // Mocked field values\n selectTarget: 'any',\n getType: 'analytics'\n };\n\n // Call runCode to run the template's code.\n let variableResult = runCode(mockData);\n\n // Verify that the variable returns a result.\n assertThat(variableResult).isNotEqualTo(undefined);\n- name: functional\n code: |-\n const mockData = {\n // Mocked field values\n selectTarget: 'any',\n getType: 'functional'\n };\n\n // Call runCode to run the template's code.\n let variableResult = runCode(mockData);\n\n // Verify that the variable returns a result.\n assertThat(variableResult).isNotEqualTo(undefined);\n- name: personalization\n code: |-\n const mockData = {\n // Mocked field values\n selectTarget: 'any',\n getType: 'personalization'\n };\n\n // Call runCode to run the template's code.\n let variableResult = runCode(mockData);\n\n // Verify that the variable returns a result.\n assertThat(variableResult).isNotEqualTo(undefined);\n- name: security\n code: |-\n const mockData = {\n // Mocked field values\n selectTarget: 'any',\n getType: 'security'\n };\n\n // Call runCode to run the template's code.\n let variableResult = runCode(mockData);\n\n // Verify that the variable returns a result.\n assertThat(variableResult).isNotEqualTo(undefined);\n- name: custom - testC\n code: |-\n const mockData = {\n // Mocked field values\n selectTarget: 'any',\n getType: 'custom',\n customName: 'testC'\n };\n\n // Call runCode to run the template's code.\n let variableResult = runCode(mockData);\n\n // Verify that the variable returns a result.\n assertThat(variableResult).isNotEqualTo(undefined);\n\n\n___NOTES___\n\nCreated on 2021/6/21 12:59:49\n\n\n", 510 | "galleryReference": { 511 | "host": "github.com", 512 | "owner": "Ayudante", 513 | "repository": "gtm-consent-state", 514 | "version": "78df2c93fc26f5c6cbcb1fc03e5bbf9580744360", 515 | "signature": "147f82d1b3183e6f91614cdeefcee3739a4baef634734cb6ca82bd1f156de31c" 516 | } 517 | }, 518 | { 519 | "accountId": "6060538801", 520 | "containerId": "95560929", 521 | "templateId": "17", 522 | "name": "Consent Mode (Google tags)", 523 | "fingerprint": "1668620266040", 524 | "templateData": "___TERMS_OF_SERVICE___\n\nBy creating or modifying this file you agree to Google Tag Manager's Community\nTemplate Gallery Developer Terms of Service available at\nhttps://developers.google.com/tag-manager/gallery-tos (or such other URL as\nGoogle may provide), as modified from time to time.\n\n\n___INFO___\n\n{\n \"type\": \"TAG\",\n \"id\": \"cvt_temp_public_id\",\n \"__wm\": \"VGVtcGFsdGUtQXV0aG9yX0NvbnNlbnRNb2RlLVNpbW8tQWhhdmE\\u003d\",\n \"version\": 1,\n \"securityGroups\": [],\n \"displayName\": \"Consent Mode (Google tags)\",\n \"categories\": [\n \"UTILITY\",\n \"ANALYTICS\",\n \"ADVERTISING\"\n ],\n \"brand\": {\n \"id\": \"github.com_gtm-templates-simo-ahava\",\n \"displayName\": \"gtm-templates-simo-ahava\",\n \"thumbnail\": \"data:image/png;base64,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\\u003d\\u003d\"\n },\n \"description\": \"Adjust tag behavior based on consent. This template utilizes Google\\u0027s Consent API and can be used to adjust how Google\\u0027s advertising and analytics use cookies and process ad identifiers.\",\n \"containerContexts\": [\n \"WEB\"\n ]\n}\n\n\n___TEMPLATE_PARAMETERS___\n\n[\n {\n \"type\": \"SELECT\",\n \"name\": \"command\",\n \"displayName\": \"Consent Command\",\n \"selectItems\": [\n {\n \"value\": \"default\",\n \"displayValue\": \"Default\"\n },\n {\n \"value\": \"update\",\n \"displayValue\": \"Update\"\n }\n ],\n \"simpleValueType\": true,\n \"help\": \"\\u003cstrong\\u003eDefault\\u003c/strong\\u003e means that you establish consent settings the site falls back on until such a time that the Update command is executed. \\u003cstrong\\u003eUpdate\\u003c/strong\\u003e is what you\\u0027d use once you\\u0027ve retrieved a consent status from the user.\",\n \"defaultValue\": \"default\",\n \"alwaysInSummary\": true\n },\n {\n \"type\": \"GROUP\",\n \"name\": \"defaultSettings\",\n \"displayName\": \"Default Consent Settings\",\n \"groupStyle\": \"NO_ZIPPY\",\n \"subParams\": [\n {\n \"type\": \"PARAM_TABLE\",\n \"name\": \"settingsTable\",\n \"paramTableColumns\": [\n {\n \"param\": {\n \"type\": \"SELECT\",\n \"name\": \"ad_storage\",\n \"displayName\": \"Advertising\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\",\n \"help\": \"If set to \\u003cstrong\\u003edenied\\u003c/strong\\u003e, Google\\u0027s advertising tags and pixels will not be able to read or write first-party cookies. The use of third-party cookies is limited to only spam and fraud detection purposes. \\u003ca href\\u003d\\\"https://support.google.com/analytics/answer/9976101#behavior\\\"\\u003eMore information\\u003c/a\\u003e\"\n },\n \"isUnique\": false\n },\n {\n \"param\": {\n \"type\": \"SELECT\",\n \"name\": \"analytics_storage\",\n \"displayName\": \"Analytics\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\",\n \"help\": \"If set to \\u003cstrong\\u003edenied\\u003c/strong\\u003e, Google Analytics tags will not read or write the first-party cookie, and data collected to Google Analytics will not utilize persistent cookie identifiers (the identifiers are reset with every page load). \\u003ca href\\u003d\\\"https://support.google.com/analytics/answer/9976101#behavior\\\"\\u003eMore information\\u003c/a\\u003e.\"\n },\n \"isUnique\": false\n },\n {\n \"param\": {\n \"type\": \"SELECT\",\n \"name\": \"personalization_storage\",\n \"displayName\": \"Personalization\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\"\n },\n \"isUnique\": false\n },\n {\n \"param\": {\n \"type\": \"SELECT\",\n \"name\": \"functionality_storage\",\n \"displayName\": \"Functionality\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\"\n },\n \"isUnique\": false\n },\n {\n \"param\": {\n \"type\": \"SELECT\",\n \"name\": \"security_storage\",\n \"displayName\": \"Security\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\"\n },\n \"isUnique\": false\n },\n {\n \"param\": {\n \"type\": \"TEXT\",\n \"name\": \"wait_for_update\",\n \"displayName\": \"Wait for Update\",\n \"simpleValueType\": true,\n \"valueUnit\": \"milliseconds\",\n \"defaultValue\": 500,\n \"help\": \"How long to wait (in milliseconds) for an \\u003cstrong\\u003eUpdate\\u003c/strong\\u003e command before firing Google tags that have been queued up.\"\n },\n \"isUnique\": false\n },\n {\n \"param\": {\n \"type\": \"TEXT\",\n \"name\": \"regions\",\n \"displayName\": \"Regions\",\n \"simpleValueType\": true,\n \"defaultValue\": \"all\",\n \"help\": \"Apply this setting to users from these \\u003ca href\\u003d\\\"https://en.wikipedia.org/wiki/ISO_3166-2\\\"\\u003eregions\\u003c/a\\u003e (provide a comma-separated list). If you select \\u003cstrong\\u003eall\\u003c/strong\\u003e, the setting will apply to all users.\"\n },\n \"isUnique\": false\n }\n ],\n \"newRowButtonText\": \"Add Setting\",\n \"editRowTitle\": \"Edit Setting\",\n \"newRowTitle\": \"Add Setting\",\n \"valueValidators\": [\n {\n \"type\": \"TABLE_ROW_COUNT\",\n \"args\": [\n 1\n ],\n \"errorMessage\": \"You must add at least one default setting.\"\n }\n ]\n }\n ],\n \"enablingConditions\": [\n {\n \"paramName\": \"command\",\n \"paramValue\": \"default\",\n \"type\": \"EQUALS\"\n }\n ]\n },\n {\n \"type\": \"GROUP\",\n \"name\": \"updateSettings\",\n \"displayName\": \"Update Consent Settings\",\n \"groupStyle\": \"NO_ZIPPY\",\n \"subParams\": [\n {\n \"type\": \"SELECT\",\n \"name\": \"update_ad_storage\",\n \"displayName\": \"Advertising\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\",\n \"help\": \"If set to \\u003cstrong\\u003edenied\\u003c/strong\\u003e, Google\\u0027s advertising tags and pixels will not be able to read or write first-party cookies. The use of third-party cookies is limited to only spam and fraud detection purposes. \\u003ca href\\u003d\\\"https://support.google.com/analytics/answer/9976101#behavior\\\"\\u003eMore information\\u003c/a\\u003e.\"\n },\n {\n \"type\": \"SELECT\",\n \"name\": \"update_analytics_storage\",\n \"displayName\": \"Analytics\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\",\n \"help\": \"If set to \\u003cstrong\\u003edenied\\u003c/strong\\u003e, Google Analytics tags will not read or write analytics cookies, and data collected to Google Analytics will not utilize persistent cookie identifiers (the identifiers are reset with every page load). \\u003ca href\\u003d\\\"https://support.google.com/analytics/answer/9976101#behavior\\\"\\u003eMore information\\u003c/a\\u003e.\"\n },\n {\n \"type\": \"SELECT\",\n \"name\": \"update_personalization_storage\",\n \"displayName\": \"Personalization\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\"\n },\n {\n \"type\": \"SELECT\",\n \"name\": \"update_functionality_storage\",\n \"displayName\": \"Functionality\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\"\n },\n {\n \"type\": \"SELECT\",\n \"name\": \"update_security_storage\",\n \"displayName\": \"Security\",\n \"macrosInSelect\": true,\n \"selectItems\": [\n {\n \"value\": \"granted\",\n \"displayValue\": \"granted\"\n },\n {\n \"value\": \"denied\",\n \"displayValue\": \"denied\"\n }\n ],\n \"simpleValueType\": true,\n \"defaultValue\": \"granted\"\n }\n ],\n \"enablingConditions\": [\n {\n \"paramName\": \"command\",\n \"paramValue\": \"update\",\n \"type\": \"EQUALS\"\n }\n ]\n },\n {\n \"type\": \"GROUP\",\n \"name\": \"other\",\n \"displayName\": \"Other Settings\",\n \"groupStyle\": \"ZIPPY_OPEN\",\n \"subParams\": [\n {\n \"type\": \"CHECKBOX\",\n \"name\": \"url_passthrough\",\n \"checkboxText\": \"Pass Ad Click Information Through URLs\",\n \"simpleValueType\": true,\n \"help\": \"Check this if you want internal links to pass advertising identifiers (\\u003cstrong\\u003egclid\\u003c/strong\\u003e, \\u003cstrong\\u003edclid\\u003c/strong\\u003e, \\u003cstrong\\u003egclsrc\\u003c/strong\\u003e, \\u003cstrong\\u003e_gl\\u003c/strong\\u003e) in the link URL while waiting for consent to be granted.\"\n },\n {\n \"type\": \"CHECKBOX\",\n \"name\": \"ads_data_redaction\",\n \"checkboxText\": \"Redact Ads Data\",\n \"simpleValueType\": true,\n \"help\": \"If this is checked \\u003cstrong\\u003eand\\u003c/strong\\u003e Advertising consent status is \\u003cstrong\\u003edenied\\u003c/strong\\u003e, Google\\u0027s advertising tags will drop all advertising identifiers from the requests, and traffic will be routed through cookieless domains.\"\n },\n {\n \"type\": \"CHECKBOX\",\n \"name\": \"sendDataLayer\",\n \"checkboxText\": \"Push dataLayer Event\",\n \"simpleValueType\": true,\n \"help\": \"When consent is set to \\\"default\\\", a dataLayer event with \\u003cstrong\\u003eevent: \\u0027gtm_consent_default\\u0027\\u003c/strong\\u003e is sent, together with consent state for both \\u003cstrong\\u003ead_storage\\u003c/strong\\u003e and \\u003cstrong\\u003eanalytics_storage\\u003c/strong\\u003e. When an \\\"update\\\" is fired, a dataLayer event with \\u003cstrong\\u003eevent: \\u0027gtm_consent_update\\u0027\\u003c/strong\\u003e is pushed together with details about the updated consent state.\"\n },\n {\n \"type\": \"CHECKBOX\",\n \"name\": \"sendGtag\",\n \"checkboxText\": \"Fire the Global Site Tag (gtag) command\",\n \"simpleValueType\": true,\n \"help\": \"Only check this if you also want to generate a gtag() command for consent. This should be unnecessary, but the option is left here for compatibility.\",\n \"defaultValue\": false\n }\n ]\n }\n]\n\n\n___SANDBOXED_JS_FOR_WEB_TEMPLATE___\n\nconst dataLayerPush = require('createQueue')('dataLayer');\nconst gtag = require('createArgumentsQueue')('gtag', 'dataLayer');\nconst gtagSet = require('gtagSet');\nconst log = require('logToConsole');\nconst makeTableMap = require('makeTableMap');\nconst setDefaultConsentState = require('setDefaultConsentState');\nconst updateConsentState = require('updateConsentState');\n\n// Set advanced settings\ngtagSet({\n url_passthrough: data.url_passthrough || false,\n ads_data_redaction: data.ads_data_redaction || false\n});\n\n// dataLayer.push helper\nconst dlPush = (isDefault, ads, analytics, personalization, functionality, security, region) => {\n dataLayerPush({\n event: 'gtm_consent_' + (isDefault ? 'default' : 'update'),\n ad_storage: ads,\n analytics_storage: analytics,\n personalization_storage: personalization,\n functionality_storage: functionality,\n security_storage: security,\n consent_region: region\n });\n};\n\n// Process default consent state\nif (data.command === 'default') {\n data.settingsTable.forEach(setting => {\n const settingObject = {\n ad_storage: setting.ad_storage,\n analytics_storage: setting.analytics_storage,\n personalization_storage: setting.personalization_storage,\n functionality_storage: setting.functionality_storage,\n security_storage: setting.security_storage,\n wait_for_update: setting.wait_for_update\n };\n if (setting.regions !== 'all') {\n settingObject.region = setting.regions.split(',').map(r => r.trim());\n }\n setDefaultConsentState(settingObject);\n if (data.sendGtag) gtag('consent', 'default', settingObject);\n if (data.sendDataLayer) {\n dlPush(true, setting.ad_storage, setting.analytics_storage, setting.personalization_storage, setting.functionality_storage, setting.security_storage, settingObject.region);\n }\n });\n}\n\n// Process updated consent state\nif (data.command === 'update') {\n if (data.sendGtag) {\n gtag('consent', 'update', {\n ad_storage: data.update_ad_storage,\n analytics_storage: data.update_analytics_storage,\n personalization_storage: data.update_personalization_storage,\n functionality_storage: data.update_functionality_storage,\n security_storage: data.update_security_storage\n });\n }\n updateConsentState({\n ad_storage: data.update_ad_storage,\n analytics_storage: data.update_analytics_storage,\n personalization_storage: data.update_personalization_storage,\n functionality_storage: data.update_functionality_storage,\n security_storage: data.update_security_storage\n });\n if (data.sendDataLayer) {\n dlPush(false, data.update_ad_storage, data.update_analytics_storage, data.update_personalization_storage, data.update_functionality_storage, data.update_security_storage);\n }\n}\n\n// Call data.gtmOnSuccess when the tag is finished.\ndata.gtmOnSuccess();\n\n\n___WEB_PERMISSIONS___\n\n[\n {\n \"instance\": {\n \"key\": {\n \"publicId\": \"logging\",\n \"versionId\": \"1\"\n },\n \"param\": [\n {\n \"key\": \"environments\",\n \"value\": {\n \"type\": 1,\n \"string\": \"debug\"\n }\n }\n ]\n },\n \"clientAnnotations\": {\n \"isEditedByUser\": true\n },\n \"isRequired\": true\n },\n {\n \"instance\": {\n \"key\": {\n \"publicId\": \"access_globals\",\n \"versionId\": \"1\"\n },\n \"param\": [\n {\n \"key\": \"keys\",\n \"value\": {\n \"type\": 2,\n \"listItem\": [\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"key\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n },\n {\n \"type\": 1,\n \"string\": \"execute\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"gtag\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"key\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n },\n {\n \"type\": 1,\n \"string\": \"execute\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"dataLayer\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": false\n }\n ]\n }\n ]\n }\n }\n ]\n },\n \"clientAnnotations\": {\n \"isEditedByUser\": true\n },\n \"isRequired\": true\n },\n {\n \"instance\": {\n \"key\": {\n \"publicId\": \"access_consent\",\n \"versionId\": \"1\"\n },\n \"param\": [\n {\n \"key\": \"consentTypes\",\n \"value\": {\n \"type\": 2,\n \"listItem\": [\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"ad_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"analytics_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"wait_for_update\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"personalization_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"functionality_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n }\n ]\n },\n {\n \"type\": 3,\n \"mapKey\": [\n {\n \"type\": 1,\n \"string\": \"consentType\"\n },\n {\n \"type\": 1,\n \"string\": \"read\"\n },\n {\n \"type\": 1,\n \"string\": \"write\"\n }\n ],\n \"mapValue\": [\n {\n \"type\": 1,\n \"string\": \"security_storage\"\n },\n {\n \"type\": 8,\n \"boolean\": true\n },\n {\n \"type\": 8,\n \"boolean\": true\n }\n ]\n }\n ]\n }\n }\n ]\n },\n \"clientAnnotations\": {\n \"isEditedByUser\": true\n },\n \"isRequired\": true\n },\n {\n \"instance\": {\n \"key\": {\n \"publicId\": \"write_data_layer\",\n \"versionId\": \"1\"\n },\n \"param\": [\n {\n \"key\": \"keyPatterns\",\n \"value\": {\n \"type\": 2,\n \"listItem\": [\n {\n \"type\": 1,\n \"string\": \"url_passthrough\"\n },\n {\n \"type\": 1,\n \"string\": \"ads_data_redaction\"\n }\n ]\n }\n }\n ]\n },\n \"clientAnnotations\": {\n \"isEditedByUser\": true\n },\n \"isRequired\": true\n }\n]\n\n\n___TESTS___\n\nscenarios:\n- name: gtag command created\n code: |-\n mock('createArgumentsQueue', (cmd, arr) => {\n assertThat(cmd).isEqualTo('gtag');\n assertThat(arr).isEqualTo('dataLayer');\n return () => {};\n });\n\n // Call runCode to run the template's code.\n runCode(mockData);\n\n // Verify that the tag finished successfully.\n assertApi('gtmOnSuccess').wasCalled();\n- name: default settings sent\n code: |-\n let index = 1;\n mockData.sendGtag = true;\n mock('createArgumentsQueue', () => {\n return function() {\n if (arguments[0] === 'consent' && index === 1) {\n assertThat(arguments[2]).isEqualTo({\n ad_storage: 'granted',\n analytics_storage: 'denied',\n personalization_storage: 'denied',\n functionality_storage: 'denied',\n security_storage: 'denied',\n wait_for_update: 500\n });\n index++;\n } else if (arguments[0] === 'consent' && index === 2) {\n assertThat(arguments[2]).isEqualTo({\n ad_storage: 'denied',\n analytics_storage: 'granted',\n personalization_storage: 'granted',\n functionality_storage: 'granted',\n security_storage: 'granted',\n wait_for_update: 1000,\n region: ['ES', 'US-AK']\n });\n }\n };\n });\n // Call runCode to run the template's code.\n runCode(mockData);\n\n // Verify that the tag finished successfully.\n assertApi('setDefaultConsentState').wasCalledWith({\n ad_storage: 'granted',\n analytics_storage: 'denied',\n personalization_storage: 'denied',\n functionality_storage: 'denied',\n security_storage: 'denied',\n wait_for_update: 500\n });\n assertApi('setDefaultConsentState').wasCalledWith({\n ad_storage: 'denied',\n analytics_storage: 'granted',\n personalization_storage: 'granted',\n functionality_storage: 'granted',\n security_storage: 'granted',\n region: ['ES', 'US-AK'],\n wait_for_update: 1000\n });\n assertApi('gtmOnSuccess').wasCalled();\n- name: updated settings sent\n code: |-\n mockData.command = 'update';\n\n mock('createArgumentsQueue', () => {\n return function() {\n if (arguments[0] === 'consent') {\n assertThat(arguments[2]).isEqualTo({\n ad_storage: 'denied',\n analytics_storage: 'granted',\n personalization_storage: 'granted',\n functionality_storage: 'granted',\n security_storage: 'granted'\n });\n }\n };\n });\n // Call runCode to run the template's code.\n runCode(mockData);\n\n // Verify that the tag finished successfully.\n assertApi('updateConsentState').wasCalledWith({\n ad_storage: 'denied',\n analytics_storage: 'granted',\n personalization_storage: 'granted',\n functionality_storage: 'granted',\n security_storage: 'granted'\n });\n assertApi('gtmOnSuccess').wasCalled();\n- name: extra settings sent\n code: |-\n mock('gtagSet', (obj) => {\n assertThat(obj.url_passthrough).isEqualTo(true);\n assertThat(obj.ads_data_redaction).isEqualTo(true);\n });\n // Call runCode to run the template's code.\n runCode(mockData);\n\n // Verify that the tag finished successfully.\n assertApi('gtmOnSuccess').wasCalled();\n- name: dataLayer events generated\n code: \"mockData.sendDataLayer = true;\\n\\nlet dlCalled = 0;\\n\\nmock('createQueue',\\\n \\ name => {\\n return o => {\\n require('logToConsole')(o);\\n if (o.event\\\n \\ === 'gtm_consent_default' && o.ad_storage === 'granted' && o.analytics_storage\\\n \\ === 'denied' && o.personalization_storage === 'denied') dlCalled++;\\n if\\\n \\ (o.event === 'gtm_consent_default' && o.ad_storage === 'denied' && o.analytics_storage\\\n \\ === 'granted' && o.personalization_storage === 'granted' && o.consent_region.join()\\\n \\ === 'ES,US-AK') dlCalled++;\\n };\\n});\\n \\n// Call runCode to run the template's\\\n \\ code.\\nrunCode(mockData);\\n\\n// Verify that the tag finished successfully.\\n\\\n assertApi('gtmOnSuccess').wasCalled();\\nassertThat(dlCalled, 'dataLayer not called\\\n \\ with correct arguments').isEqualTo(2);\"\nsetup: |-\n const mockData = {\n command: 'default',\n settingsTable: [{\n ad_storage: 'granted',\n analytics_storage: 'denied',\n personalization_storage: 'denied',\n functionality_storage: 'denied',\n security_storage: 'denied',\n wait_for_update: 500,\n regions: 'all'\n },{\n ad_storage: 'denied',\n analytics_storage: 'granted',\n personalization_storage: 'granted',\n functionality_storage: 'granted',\n security_storage: 'granted',\n wait_for_update: 1000,\n regions: 'ES, US-AK'\n }],\n update_analytics_storage: 'granted',\n update_ad_storage: 'denied',\n update_personalization_storage: 'granted',\n update_functionality_storage: 'granted',\n update_security_storage: 'granted',\n url_passthrough: true,\n ads_data_redaction: true,\n sendDataLayer: false,\n sendGtag: false\n };\n\n\n___NOTES___\n\nCreated on 07/10/2020, 10:39:35\n\n\n", 525 | "galleryReference": { 526 | "host": "github.com", 527 | "owner": "gtm-templates-simo-ahava", 528 | "repository": "consent-mode", 529 | "version": "ab3c243d7bcce3ae417eef63296a9f653ee685f0", 530 | "signature": "07bf93bb2cb76b82ac1eb18d3a9f44b9daa85c0b165092dd2a4a1732ac5d1116" 531 | } 532 | } 533 | ] 534 | } 535 | } -------------------------------------------------------------------------------- /docs/img/livewire-cookie-consent-modal1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinschenk/livewire-cookie-consent/f59f5225270d210ad2a32516fd0a298dc2338976/docs/img/livewire-cookie-consent-modal1.jpg -------------------------------------------------------------------------------- /docs/img/livewire-cookie-consent-modal2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinschenk/livewire-cookie-consent/f59f5225270d210ad2a32516fd0a298dc2338976/docs/img/livewire-cookie-consent-modal2.jpg -------------------------------------------------------------------------------- /public/LaravelLogo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/lang/de/texts.php: -------------------------------------------------------------------------------- 1 | 'Alle Cookies akzeptieren', 5 | 'alert_essentials_only' => 'Nur notwendige Cookies akzeptieren', 6 | 'alert_settings' => 'Cookies anpassen', 7 | 'alert_text' => 'Indem Sie „Alle Cookies akzeptieren“ wählen, stimmen Sie der Verwendung von Cookies zu, die uns helfen, Ihnen ein besseres Benutzererlebnis zu bieten und die Nutzung der Website zu analysieren. Indem Sie auf „Einstellungen anpassen“ klicken, können Sie auswählen, welche Cookies Sie zulassen möchten. Nur die wesentlichen Cookies sind für das reibungslose Funktionieren unserer Website erforderlich und können nicht abgelehnt werden', 8 | 'alert_title' => ' verwendet Cookies', 9 | 'alert_essential_only' => 'Nur notwendige Cookies akzeptieren', 10 | 'setting_analytics' => 'Analytische Cookies', 11 | 'setting_analytics_text' => 'ermöglichen es uns, die Nutzung der Website zu analysieren und das Besuchererlebnis zu verbessern.', 12 | 'setting_essential' => 'Unverzichtbare Cookies', 13 | 'setting_essential_text' => 'sind aus technischen Gründen erforderlich. Ohne sie funktioniert diese Website möglicherweise nicht richtig.', 14 | 'setting_functional' => 'Funktionale Cookies', 15 | 'setting_functional_text' => 'sind für bestimmte Funktionen der Website erforderlich. Ohne sie können einige Funktionen deaktiviert werden.', 16 | 'setting_marketing' => 'Marketing-Cookies', 17 | 'setting_marketing_text' => 'ermöglichen es uns, Ihre Erfahrung zu personalisieren und Ihnen relevante Inhalte und Angebote auf dieser Website und anderen Websites zuzusenden.', 18 | 'settings_accept_all' => 'Alle Cookies akzeptieren', 19 | 'settings_cancel' => 'Abbrechen', 20 | 'settings_close' => 'Schließen', 21 | 'settings_save' => 'Meine Auswahl speichern', 22 | 'settings_title' => 'Cookie-Einstellungen', 23 | 'settings_text' => 'Unsere Website speichert vier Arten von Cookies. Sie können jederzeit wählen, welche Cookies Sie akzeptieren und welche Sie ablehnen. Weitere Informationen darüber, was Cookies sind und welche Arten von Cookies wir speichern, finden Sie in unserer Cookie-Richtlinie.' 24 | ]; 25 | -------------------------------------------------------------------------------- /resources/lang/en/texts.php: -------------------------------------------------------------------------------- 1 | 'Accept all cookies', 5 | 'alert_essentials_only' => 'Accept only necessary cookies', 6 | 'alert_settings' => 'Adjust your preferences', 7 | 'alert_text' => 'By choosing "Accept all cookies" you agree to the use of cookies to help us provide you with a better user experience and to analyse website usage. By clicking "Adjust your preferences" you can choose which cookies to allow. Only the essential cookies are necessary for the proper functioning of our website and cannot be refused', 8 | 'alert_title' => ' uses cookies', 9 | 'alert_essential_only' => 'Accept only necessary cookies', 10 | 'setting_analytics' => 'Analytical cookies', 11 | 'setting_analytics_text' => 'allow us to analyse website use and to improve the visitor\'s experience.', 12 | 'setting_essential' => 'Essential cookies', 13 | 'setting_essential_text' => 'are necessary for technical reasons. Without them, this website may not function properly.', 14 | 'setting_functional' => 'Functional cookies', 15 | 'setting_functional_text' => 'are necessary for specific functionality on the website. Without them, some features may be disabled.', 16 | 'setting_marketing' => 'Marketing cookies', 17 | 'setting_marketing_text' => 'allow us to personalise your experience and to send you relevant content and offers, on this website and other websites.', 18 | 'settings_accept_all' => 'Accept all cookies', 19 | 'settings_cancel' => 'Cancel', 20 | 'settings_close' => 'Close', 21 | 'settings_save' => 'Save my selection', 22 | 'settings_title' => 'Cookie settings', 23 | 'settings_text' => 'Our website stores four types of cookies. At any time you can choose which cookies you accept and which you refuse. You can read more about what cookies are and what types of cookies we store in our Cookie Policy.' 24 | ]; 25 | -------------------------------------------------------------------------------- /resources/lang/es/texts.php: -------------------------------------------------------------------------------- 1 | 'Aceptar todas las cookies', 5 | 'alert_essential_only' => 'Aceptar solo las cookies necesarias', 6 | 'alert_essentials_only' => 'Aceptar solo las cookies necesarias', 7 | 'alert_settings' => 'Gestión Cookies', 8 | 'alert_text' => 'Al elegir "Aceptar todas las cookies", acepta el uso de cookies para ayudarnos a brindarle una mejor experiencia de usuario y analizar el uso del sitio web. Al hacer clic en "Ajuste sus preferencias" puede elegir qué cookies permitir. Solo las cookies esenciales son necesarias para el correcto funcionamiento de nuestro sitio web y no se pueden rechazar.', 9 | 'alert_title' => ' utiliza cookies', 10 | 'setting_analytics' => 'Cookies analíticas', 11 | 'setting_analytics_text' => 'nos permiten analizar el uso del sitio web y mejorar la experiencia del visitante.', 12 | 'setting_essential' => 'Cookies esenciales', 13 | 'setting_essential_text' => 'son necesarios por razones técnicas. Sin ellos, es posible que este sitio web no funcione correctamente.', 14 | 'setting_functional' => 'Cookies funcionales', 15 | 'setting_functional_text' => 'son necesarios para una funcionalidad específica en el sitio web. Sin ellos, algunas características pueden estar deshabilitadas.', 16 | 'setting_marketing' => 'Cookies de marketing', 17 | 'setting_marketing_text' => 'nos permite personalizar su experiencia y enviarle contenido y ofertas relevantes, en este sitio web y en otros sitios web.', 18 | 'settings_accept_all' => 'Aceptar todas las cookies', 19 | 'settings_cancel' => 'Cancelar', 20 | 'settings_close' => 'Cerrar', 21 | 'settings_save' => 'Guardar mi selección', 22 | 'settings_title' => 'Configuración de cookies', 23 | 'settings_text' => 'Nuestro sitio web almacena cuatro tipos de cookies. En cualquier momento puede elegir qué cookies acepta y cuáles rechaza. Puede obtener más información sobre qué son las cookies y qué tipos de cookies almacenamos en nuestra Política de cookies.' 24 | ]; 25 | -------------------------------------------------------------------------------- /resources/views/cookie-consent-edit.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $locale = $app->getLocale(); 3 | @endphp 4 | 5 |27 | {!! trans('livewire-cookie-consent::texts.settings_text', [ 'policyUrl' => config("livewire-cookie-consent.policy_url_$locale")]) !!} 28 |
29 | 30 | {{-- gtm-cookie-button is trigger in gtm --}} 31 | 39 | 40 | 41 | 42 | 94 |cookie is set
--}} 3 | @else 4 | {{--cookie is not set
--}} 5 | {{--cookie is set
--}} 3 | @else 4 | {{--cookie is not set
--}} 5 | {{--