Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@
/vendor
/node_modules
package-lock.json
composer.lock
composer.lock
.yarn/*
!.yarn/patches
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*
.yarnrc.yml
Binary file added assets/screenshot-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshot-filament.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 16 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,25 @@
"name": "Kristof Serré",
"email": "[email protected]",
"homepage": "https://www.statik.be"
},
{
"name": "Seppe Van Besauw",
"email": "[email protected]",
"homepage": "https://www.statik.be"
}
],
"homepage": "https://github.com/statikbe/laravel-cookie-consent",
"keywords": ["Laravel", "cookie", "gdpr"],
"keywords": [
"Laravel",
"cookie",
"gdpr",
"Filament",
"cookie-banner",
"Google Tag Manager",
"privacy",
"GDPR",
"consent"
],
"license": "MIT",
"require": {
"php": "^8.0",
Expand Down
7 changes: 6 additions & 1 deletion config/cookie-consent.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<?php

return [
/**
* Theme to use for the cookie consent popup.
* Available options: 'default', 'filament'.
*/
'theme' => 'default',
'cookie_key' => '__cookie_consent',
'cookie_value_analytics' => '2',
'cookie_value_marketing' => '3',
Expand All @@ -13,4 +18,4 @@
'policy_url_en' => env('COOKIE_POLICY_URL_EN', null),
'policy_url_fr' => env('COOKIE_POLICY_URL_FR', null),
'policy_url_nl' => env('COOKIE_POLICY_URL_NL', null),
];
];
1 change: 1 addition & 0 deletions mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"/public/js/cookie-consent.js": "/public/js/cookie-consent.js",
"/public/js/cookie-consent-filament.js": "/public/js/cookie-consent-filament.js",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kan dat kwaad dat die hier allebei staan? Misschien ook in readme zetten dat ze die verwijderen afhankelijk van de theme?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mix-manifest.json is auto-generated tijdens de build van de package. Dus niet de bedoeling dat we deze manueel gaan bewerken.
In principe is het de bedoeling dat onze package pre-built js files aanbied aan de consumer en niet de bedoeling dat de end user in zijn vendor map changes moet maken om dan de juiste theme files te builden.

That said, deze mix manifest klopt wel nog niet zie ik, vergeten een nieuwe build te maken na onze changes donderdag, so fixed that!

"/public/css/cookie-consent.css": "/public/css/cookie-consent.css"
}
1 change: 1 addition & 0 deletions public/js/cookie-consent-filament.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion public/js/cookie-consent.js

Large diffs are not rendered by default.

106 changes: 70 additions & 36 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<p align="center"><img src="docs/img/card.png" alt="Card of Laravel Cookie consent"></p>

# Laravel cookie consent modal

[![Latest Version on Packagist](https://img.shields.io/packagist/v/statikbe/laravel-cookie-consent.svg?style=flat-square)](https://packagist.org/packages/statikbe/llaravel-cookie-consent)
[![Total Downloads](https://img.shields.io/packagist/dt/statikbe/laravel-cookie-consent.svg?style=flat-square)](https://packagist.org/packages/statikbe/laravel-cookie-consent)

![Modal cookie consent](docs/img/modal.png?raw=true 'Modal for Cookie consent')

![Modal cookie consent](docs/img/modal.png?raw=true "Modal for Cookie consent")

![Preferences Modal](docs/img/preferences.png?raw=true "Preferences for cookies")

![Preferences Modal](docs/img/preferences.png?raw=true 'Preferences for cookies')

The package includes a script & styling for a cookie banner and a modal where the visitor can select his/her cookie preferences.

Expand All @@ -17,49 +16,52 @@ This package is mainly based on the one from spatie: https://github.com/spatie/l
With the only exception that you can choose which cookies you enable.
This only works when Google Tag Manager is correctly configured (some regex config based on the value set in the cookie).

* [Upgrading](upgrading.md)
* [Installation](#installation)
* [Usage](#usage)
* [Customising the dialog texts](#customising-the-dialog-texts)
+ [Customising the dialog contents](#customising-the-dialog-contents)
+ [Publishing](#publishing)
- [Config](#config)
- [Translations](#translations)
- [Views](#views)
* [Configure Google Tag Manager](#configure-google-tag-manager)
* [Security](#security)
* [License](#license)

- [Upgrading](upgrading.md)
- [Installation](#installation)
- [Usage](#usage)
- [Customising the dialog texts](#customising-the-dialog-texts)
- [Customising the dialog contents](#customising-the-dialog-contents)
- [Publishing](#publishing)
- [Config](#config)
- [Translations](#translations)
- [Views](#views)
- [Configure Google Tag Manager](#configure-google-tag-manager)
- [Security](#security)
- [License](#license)

## Upgrading

You can find our upgrading guides [here](upgrading.md).

## Installation

You can install the package via composer:

``` bash
```bash
composer require statikbe/laravel-cookie-consent
```

The package will automatically register itself.

First of all **you need to** publish the javascript and css files:

```bash
php artisan vendor:publish --provider="Statikbe\CookieConsent\CookieConsentServiceProvider" --tag="cookie-public"
```

Include the css/cookie-consent.css into your base.blade.php or any other base template you use.

```
<link rel="stylesheet" type="text/css" href="{{asset("vendor/cookie-consent/css/cookie-consent.css")}}">
```

The javascript file is included in the cookie snippet and will be added at the end of your body.

## Usage

Instead of including a snippet in your view, we will automatically add it. This is done using middleware using two methods:

__For Laravel 11.x and newer__
**For Laravel 11.x and newer**

```php
// bootstrap/app.php
Expand All @@ -80,7 +82,8 @@ __For Laravel 11.x and newer__
})

```
__For Laravel 10.x and earlier__

**For Laravel 10.x and earlier**

```php
// app/Http/Kernel.php
Expand All @@ -96,8 +99,8 @@ class Kernel extends HttpKernel
// ...
'cookie-consent' => \Statikbe\CookieConsent\CookieConsentMiddleware::class,
];


// routes/web.php
Route::group([
'middleware' => ['cookie-consent']
Expand All @@ -118,16 +121,17 @@ php artisan vendor:publish --provider="Statikbe\CookieConsent\CookieConsentServi
```

This will publish this file to `resources/lang/vendor/cookieConsent/en/texts.php`.
```php

return [
'alert_title' => 'Deze website gebruikt cookies',
'setting_analytics' => 'Analytische cookies',
];
```

If you want to translate the values to, for example, English, just copy that file over to `resources/lang/vendor/cookieConsent/fr/texts.php` and fill in the English translations.


```php

return [
'alert_title' => 'Deze website gebruikt cookies',
'setting_analytics' => 'Analytische cookies',
];
```

If you want to translate the values to, for example, English, just copy that file over to `resources/lang/vendor/cookieConsent/fr/texts.php` and fill in the English translations.

### Customising the dialog contents

If you need full control over the contents of the dialog. You can publish the views of the package:
Expand All @@ -136,25 +140,52 @@ If you need full control over the contents of the dialog. You can publish the vi
php artisan vendor:publish --provider="Statikbe\CookieConsent\CookieConsentServiceProvider" --tag="cookie-views"
```

This will copy the `index` view file over to `resources/views/vendor/cookieConsent`.
This will copy the `index` view file over to `resources/views/vendor/cookieConsent`.

The `cookie-settings` view file is just a snippet you need to place somewhere onto your page. Most preferably in the footer next to the url of your cookie policy.

```html
```html
<a href="javascript:void(0)" class="js-lcc-settings-toggle">@lang('cookie-consent::texts.alert_settings')</a>
```

This gives your visitor the opportunity to change the settings again.

### Customising the theme

By default, the cookie popup will look like this:

![screenshot of default theme](./assets/screenshot-default.png)

If you are however working on a project that is using filament, you can opt to use filament componets to render your cookie popup.

To do this, configure the theme to `filament`

```
'theme' => 'filament'
```

This will render the cookie popup like so:

![screenshot of filament theme](./assets/screenshot-filament.png)

### Publishing

#### Config

```bash
php artisan vendor:publish --provider="Statikbe\CookieConsent\CookieConsentServiceProvider" --tag="cookie-config"
```

This is the contents of the published config-file:
This will read the policy urls from your env.
This will read the policy urls from your env.

```php
return [
/**
* Theme to use for the cookie consent popup.
* Available options: 'default', 'filament'.
*/
'theme' => 'default',
'cookie_key' => '__cookie_consent',
'cookie_value_analytics' => '2',
'cookie_value_marketing' => '3',
Expand All @@ -169,10 +200,13 @@ return [
'policy_url_nl' => env('COOKIE_POLICY_URL_NL', null),
];
```

You can customize some settings that work with your GTM.

#### Don't show modal on cookie policy page or other pages

If you don't want the modal to be shown on certain pages you can add the relative url to the ignored paths setting. This also accepts wildcards (see the Laravel `Str::is()` [helper](https://laravel.com/docs/9.x/helpers#method-str-is)).

```
'ignored_paths => ['/en/cookie-policy', '/api/documentation*'];
```
Expand All @@ -190,8 +224,8 @@ php artisan vendor:publish --provider="Statikbe\CookieConsent\CookieConsentServi
```

## Configure Google Tag Manager
All the steps to configure your Google Tag Manager can be found [here](docs/google-tag-manager.md).

All the steps to configure your Google Tag Manager can be found [here](docs/google-tag-manager.md).

## Security

Expand Down
114 changes: 114 additions & 0 deletions resources/js/cookie-consent-filament.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { getCookie, setCookie } from './util/cookies';

let onConsentChange;
window.cookieBannerConsentChange = (callback) => {
onConsentChange = callback;
};

document.addEventListener('alpine:init', () => {
Alpine.data('cookieConsentModal', (props) => ({
COOKIE_KEY: props.COOKIE_KEY,
IGNORED_PATHS: JSON.parse(props.IGNORED_PATHS),
COOKIE_VALUE_ANALYTICS: props.COOKIE_VALUE_ANALYTICS,
COOKIE_VALUE_MARKETING: props.COOKIE_VALUE_MARKETING,
COOKIE_VALUE_BOTH: props.COOKIE_VALUE_BOTH,
COOKIE_VALUE_NONE: props.COOKIE_VALUE_NONE,
COOKIE_EXPIRATION_DAYS: props.COOKIE_EXPIRATION_DAYS,
GTM_EVENT: props.GTM_EVENT,
SESSION_DOMAIN: props.SESSION_DOMAIN,
COOKIE_SECURE: props.COOKIE_SECURE,
checkboxAnalytics: false,
checkboxMarketing: false,
init() {
this.$nextTick(() => {
this.initialize();
});
},
// Button listeners
acceptAll() {
this.updateCookie(this.COOKIE_VALUE_BOTH);
this.closeCookieConsentModal();
this.closeCookieSettingsModal();
},
acceptEssentials() {
this.updateCookie(this.COOKIE_VALUE_NONE);
this.closeCookieConsentModal();
this.closeCookieSettingsModal();
},
openSettings() {
this.openCookieSettingsModal();
},
saveSettings() {
let cookieValue;

if (this.checkboxAnalytics && this.checkboxMarketing) {
cookieValue = this.COOKIE_VALUE_BOTH;
} else if (this.checkboxAnalytics) {
cookieValue = this.COOKIE_VALUE_ANALYTICS;
} else if (this.checkboxMarketing) {
cookieValue = this.COOKIE_VALUE_MARKETING;
} else {
cookieValue = this.COOKIE_VALUE_NONE;
}

this.updateCookie(cookieValue);
this.closeCookieConsentModal();
this.closeCookieSettingsModal();
},
// Helper functions
openCookieConsentModal() {
this.$dispatch('open-modal', { id: 'cookie-consent-modal' });
},
closeCookieConsentModal() {
this.$dispatch('close-modal', { id: 'cookie-consent-modal' });
},
openCookieSettingsModal() {
this.$dispatch('open-modal', { id: 'cookie-consent-settings-modal' });
},
closeCookieSettingsModal() {
this.$dispatch('close-modal', { id: 'cookie-consent-settings-modal' });
},
initialize() {
const ignoredPathsArray = this.IGNORED_PATHS
? this.IGNORED_PATHS.map((ignoredPath) => ignoredPath.trim())
: [];
const isIgnoredPage = ignoredPathsArray.indexOf(location.pathname) > -1;

const isRobot = /bot|google|baidu|bing|msn|duckduckbot|teoma|slurp|yandex/i.test(navigator.userAgent);

if (isRobot) return;

if (!getCookie(this.COOKIE_KEY) && !isIgnoredPage) {
this.openCookieConsentModal();
}

this.fillFormData();
},
fillFormData() {
const cookieValue = getCookie(this.COOKIE_KEY);

this.checkboxAnalytics =
cookieValue === this.COOKIE_VALUE_BOTH || cookieValue === this.COOKIE_VALUE_ANALYTICS;
this.checkboxMarketing =
cookieValue === this.COOKIE_VALUE_BOTH || cookieValue === this.COOKIE_VALUE_MARKETING;
},
updateCookie(cookieValue) {
setCookie(
this.COOKIE_KEY,
cookieValue,
this.COOKIE_EXPIRATION_DAYS,
this.SESSION_DOMAIN,
this.COOKIE_SECURE,
);

if (onConsentChange) {
onConsentChange(cookieValue);
}

// Fire GTM event if dataLayer is found
if (window.dataLayer) {
window.dataLayer.push({ event: this.GTM_EVENT });
}
},
}));
});
Loading