This is a simple, modern Consent Manager to handle cookies in the front- and backend.
The CM is capable of dealing with different languages and cookies.
Although there is no database or special backend for settings or statistics as this designed to be easily implemented for standard cases.
Type: Number
Number of categories to handle.
default: 0
Type: Boolean
If true, cookies will be stored with the selected user settings and sent with every request to the server (legacy cookie behavior).
Regardless of this setting, Easy CM will store all settings in localStorage and only send them once when the user has submitted the settings.
default: true
Type: String (list, comma-separated)
Comma-separated list of supported languages in the format:
ISO 639 code / Language name (separated by commas).
default: 'en/English'
<div
data-controller="easy-cm"
data-easy-cm-supported-languages-value="en/English,de/German,es/Spanish"
></div>Type: String
The URL endpoint where Easy CM will send the result when the user submits the cookie settings.
default: ''
REQUIRED
Type: String
URL to fetch the language data if it differs from the updateLink.
default: ''
This is the core to populate and style the pages.
The styling must be done within the response itself.
REQUIRED
Expected response format (JSON string):
{
header: 'Header text',
body: 'Body text',
accept: 'Accept button text',
acceptAll: 'Accept all button text',
acceptNecessary: 'Accept only necessary button text',
readMore: 'Text for the read more button',
bottomLinks: {
privacy: {
name: 'Privacy policy',
link: '/privacy-policy',
attributes: {
style: 'color: lightblue;',
dataTurbo: 'false',
}
}
},
categories: {
Essential: {
name: 'Essential',
header: 'Essential header text',
body: 'Essential body text',
},
Tracking: {
name: 'Tracking',
header: 'Tracking header text',
body: 'Tracking body text',
},
}
}Here is an example in PHP how to response the requested language:
$lang = $this->get('lang');
$res = $someDbFetch;
if ($lang) {
switch ($lang) {
case 'en':
$responseObj = [
'header' => $res[0]['header'],
'body' => strip_tags($res[0]['bodytext']),
'accept' => $res[1]['header'],
'acceptAll' => $res[2]['header'],
'acceptNecessary' => $res[3]['header'],
'bottomLinks' => [
'privacy' => [
'name' => 'Privacy policy',
'link' => '/privacy-policy',
'attributes' => [
'dataTurbo' => 'false',
]
]
],
'categories' => [
'Essential' => [
'name' => 'Essential',
'header' => $res[4]['header'],
'body' => strip_tags($res[4]['bodytext']),
],
'Comfort' => [
'name' => 'Comfort',
'header' => 'Comfort settings',
'body' => 'Body for comfort settings',
],
'Tracking' => [
'name' => 'Tracking',
'header' => 'Tracking settings',
'body' => 'Body for tracking settings',
],
],
'readMore' => $res[5]['header'],
'languageName' => $res[6]['header'],
];
break;
case 'de':
$responseObj = [
'header' => $res[7]['header'],
'body' => strip_tags($res[7]['bodytext']),
'accept' => $res[8]['header'],
'acceptAll' => $res[9]['header'],
'acceptNecessary' => $res[10]['header'],
'readMore' => $res[11]['header'],
'bottomLinks' => [
'privacy' => [
'name' => 'Datenschutz',
'link' => '/privacy-policy',
'attributes' => [
'dataTurbo' => 'false',
]
]
],
'categories' => [
'Essential' => [
'name' => 'Notwendige',
'header' => $res[12]['header'],
'body' => '<b>' . $res[12]['bodytext'] . '</b>',
],
'Comfort' => [
'name' => 'Komfort',
'header' => 'Komforteinstellungen',
'body' => 'Text für die Komforteinstellungen',
],
'Tracking' => [
'name' => 'Tracking',
'header' => 'Trackingeinstellungen',
'body' => 'Text für die Trackingeinstellungen',
],
],
'languageName' => $res[6]['header'],
];
break;
default:
$responseObj = [
'header' => $res[0]['header'],
'body' => strip_tags($res[0]['bodytext']),
'accept' => $res[1]['header'],
'acceptAll' => $res[2]['header'],
'acceptNecessary' => $res[3]['header'],
'categories' => [
'Essential' => [
'header' => $res[4]['header'],
'body' => strip_tags($res[4]['bodytext']),
],
'Comfort' => [
'name' => 'Comfort',
'header' => 'Comfort settings',
'body' => 'Body for comfort settings',
],
'Tracking' => [
'name' => 'Tracking',
'header' => 'Tracking settings',
'body' => 'Body for tracking settings',
],
],
'readMore' => $res[5]['header'],
'languageName' => $res[6]['header'],
];
break;
}
} else {
$responseObj = [
'header' => $res[0]['header'],
'body' => strip_tags($res[0]['bodytext']),
'accept' => $res[1]['header'],
'acceptAll' => $res[2]['header'],
'acceptNecessary' => $res[3]['header'],
'categories' => [
'Essential' => [
'header' => $res[4]['header'],
'body' => strip_tags($res[4]['bodytext']),
],
'Comfort' => [
'name' => 'Comfort',
'header' => 'Comfort settings',
'body' => 'Body for comfort settings',
],
'Tracking' => [
'name' => 'Tracking',
'header' => 'Tracking settings',
'body' => 'Body for tracking settings',
],
],
'readMore' => $res[5]['header'],
'languageName' => $res[6]['header'],
];
}Type: String (keyword)
The HTTP method to be used by Easy CM for update requests, usually 'POST' or 'GET'.
default: 'POST'
Type: String
Event name dispatched on successful completion of cookie management action.
See the setting 'eventTarget' for an example.
default: 'easyCmSuccess'
Type: String
Event name dispatched on failure of cookie management action.
default: 'easyCmFailure'
Type: String
CSS selector or element identifier to which events will be dispatched.
default: 'body'
<div
data-controller="easy-cm"
data-easy-cm-success-event-value="mySuccessEvent"
data-easy-cm-event-target-value="#targetId"
></div>The example above will dispatch the event 'mySuccessEvent' on the element with the ID of 'targetId'.
document.getElementById('targetId').addEventListener('mySuccessEvent', (e) => {
//Do some stuff
});Type: String (dash-separated keywords)
Name of the template to use for rendering the consent manager.
Possible templates include predefined names like "light-blue".
default: 'blue-light'
Possible keywords are:
Schema: 'light', 'dark'
Colors: 'blue', 'red', 'green', 'yellow', 'pink', 'brown', 'bright' and 'shady'
Type: Object
Object defining error fallback texts, used if the manager crashes or fails.
default: {}
{
en: 'Fallback text for English',
de: 'Fehlertext auf Deutsch',
}<div
data-controller="easy-cm"
data-easy-cm-error-texts-value="{en: 'Fallback text for English', de: 'Fehlertext auf Deutsch',}"
></div>Type: String (comma-separated list)
Comma-separated list of page paths where the consent manager pop-up will NOT appear.
Note: subpages are not excluded by this setting.
Important: Do NOT include a trailing slash '/' at the end for exact comparison.
default: ''
Type: Boolean
If set to true, Easy CM will wait for a specific event before rendering the consent manager.
default: false
Type: String
The event name to listen to for triggering Easy CM rendering if 'startByEvent' is enabled.
default: 'easyCmStart'
<div
id="easyCmElement"
data-controller="easy-cm"
data-easy-cm-start-by-event-value="true"
data-easy-cm-event-name-value="myStartEvent"
></div>Now you can start the rendering by dispatching the event 'myStartEvent' on the controller's element anytime.
const myEvent = new CustomEvent('myStartEvent');
setTimeout(() => {
document.getElementById('easyCmElement').dispatchEvent(myEvent);
}, 3000);Easy CM Manager helper function to trigger reopening the consent manager UI.
Dispatches the 'easyCmReopen' custom event on the first element with the 'easy-cm' controller.
Resets the submission status and prepares the manager again for display.
All previous settings are deleted.
The manager is designed to handle different categories.
A category can represent a group such as 'Essentials', 'Tracking', or even a single cookie.
There are two types of categories: required and optional.
Each category contains information about one or more cookies.
This information can be simple text or more advanced constructs, depending on the response needed.
Styling must be applied at the time of requesting the current language and can include raw HTML formatting.
A text entry can be plain or enriched content such as <b>Bold text</b> or more complex HTML elements:
<table>
<thead>
<tr>
<th class="my-th-class-one">
Cookie
</th>
<th class="my-th-class-two">
Lifetime
</th>
<th class="my-th-class-three">
Description
</th>
</tr>
</thead>
<tbody>
<tr>
<th>Analytics-Cookie</th>
<th>30 days</th>
<th>Tracks the visited pages.</th>
</tr>
<tr>
<th>Session</th>
<th>1 year</th>
<th>Stores current session information.</th>
</tr>
</tbody>
</table>
For examples and guidance on correctly defining categories, please refer to the demo page for the consent manager.
Every language response must contain specific content in JSON format for every category and the requested language.
First we need the text in the requested language of the main page of the manager.
{
"header":"The header for the main content",
"body":"The body of the main content",
"accept":"The text for the accept button",
"acceptAll":"The text for the accept all button",
"acceptNecessary":"The text for the accept necessary button",
"readMore":"The text for the read more button",
"languageName":"The name of the requested language",
}
Next we can define one or more links at the bottom of the main page.
{
"bottomLinks": {
"key-of-the-link": {
"name":"Text for the link",
"link":"/the/link",
"attributes": {
"attribute":"Some attribute value",
"style":"color: lightblue;"
}
}
}
}
Finally we must define the content for the different categories.
{
"categories": {
"key/identifier": {
"name":"Name of the category",
"header":"Header for the category page",
"body":"Body for the category page"
},
"Essential": {
"name":"Essential",
"header":"Essential cookies",
"body":"Session data is stored to make the website work."
},
"Tracking": {
"name":"Tracking",
"header":"You can write HTML to style the content of the category page to your needs.",
"body":'<span style="color: red;">Some red text</span><p class="greenText">Some green text</p>'
}
}
}
This is how the whole response should look like:
{
"header":"The header for the main content",
"body":"The body of the main content",
"accept":"The text for the accept button",
"acceptAll":"The text for the accept all button",
"acceptNecessary":"The text for the accept necessary button",
"readMore":"The text for the read more button",
"languageName":"The name of the requested language",
"bottomLinks": {
"key-of-the-link": {
"name":"Text for the link",
"link":"/the/link",
"attributes": {
"attribute":"Some attribute value",
"style":"color: lightblue;"
}
}
},
"categories": {
"key/identifier": {
"name":"Name of the category",
"header":"Header for the category page",
"body":"Body for the category page"
},
"Essential": {
"name":"Essential",
"header":"Essential cookies",
"body":"Session data is stored to make the website work."
},
"Tracking": {
"name":"Tracking",
"header":"You can write HTML to style the content of the category page to your needs.",
"body":'<span style="color: red;">Some red text</span><p class="greenText">Some green text</p>'
}
}
}
Type: String
Category name, e.g. 'Essential', 'Analytics', etc.
default: 'Essential'
REQUIRED
Type: Number
Expiration time in seconds for the category cookies.
Use -1 for session cookies.
default: -1
Type: String
Cookie domain scope.
default: ''
More information:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies
Type: String
Cookie path scope.
default: '/'
More information:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies
Type: String
SameSite attribute for cookies ('lax', 'strict', 'none').
default: 'lax'
More information:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies
Type: Boolean
Flag indicating if cookies should be secure (HTTPS only).
default: true
More information:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies
Type: Boolean
Flag indicating if the cookie is partitioned.
default: false
More information:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies
Type: Boolean
Indicates if the category is essential (required by site).
default: true
Type: Object
Object holding additional key-value pairs for category settings.
default: {}
Type: String (semi-colon-separated list)
String representation of key-value pairs in the format:
'key1=value1;key2=value2;...'
Semi-colons and equal signs should be URI encoded if used within values.
default: ''