A lightweight & gdpr compliant cookie consent plugin written in plain javascript. An "all-in-one" solution which also allows you to write your cookie policy inside it without the need of having a dedicated page.
- Key features
- Installation & Usage
- Layout options & customization
- API & config. parameters
- Manage third party scripts
- Configuration examples
- How to enable/manage revisions
- FAQ
- License
- Lightweight
- Cross-browser support (IE8+)
- Standalone (no external dependencies needed)
- GDPR compliant
- Support for multi language
- WAI-ARIA compliant
- Allows you to define different cookie categories with opt in/out toggle
- Allows you to define custom cookie tables to specify the cookies you use
-
Download the latest release or use via CDN or NPM
# CDN links https://cdn.jsdelivr.net/gh/orestbida/[email protected]/dist/cookieconsent.js https://cdn.jsdelivr.net/gh/orestbida/[email protected]/dist/cookieconsent.css
Thanks to Till Sanders for bringing the plugin on npm.
npm i vanilla-cookieconsent yarn add vanilla-cookieconsent
-
Import the plugin: add a
script
tag pointing tocookieconsent.js
<html> <head> <!-- head content --> </head> <body> <!-- body content --> <script defer src="<path-to-cookieconsent.js>"></script> </body> </html>
Note: replace
<path-to-cookieconsent.js>
with a valid path! -
Configure and run
-
As external script
-
Create a
.js
file (e.g.cookieconsent-init.js
) and import it in your html page<body> <!-- body content ... --> <script defer src="<path-to-cookieconsent.js>"></script> <script defer src="<path-to-cookieconsent-init.js>"></script> <body>
-
Configure the plugin inside
cookieconsent-init.js
// obtain plugin var cc = initCookieConsent(); // run plugin with your configuration cc.run({ current_lang: 'en', autoclear_cookies: true, // default: false theme_css: '<path-to-cookieconsent.css>', // 🚨 replace with a valid path page_scripts: true, // default: false // delay: 0, // default: 0 // auto_language: null // default: null; could also be 'browser' or 'document' // autorun: true, // default: true // force_consent: false, // default: false // hide_from_bots: false, // default: false // remove_cookie_tables: false // default: false // cookie_name: 'cc_cookie', // default: 'cc_cookie' // cookie_expiration: 182, // default: 182 (days) // cookie_domain: location.hostname, // default: current domain // cookie_path: '/', // default: root // cookie_same_site: 'Lax', // default: 'Lax' // use_rfc_cookie: false, // default: false // revision: 0, // default: 0 onAccept: function (cookie) { // ... }, onChange: function (cookie, changed_preferences) { // ... }, languages: { 'en': { consent_modal: { title: 'We use cookies!', description: 'Hi, this website uses essential cookies to ensure its proper operation and tracking cookies to understand how you interact with it. The latter will be set only after consent. <button type="button" data-cc="c-settings" class="cc-link">Let me choose</button>', primary_btn: { text: 'Accept all', role: 'accept_all' // 'accept_selected' or 'accept_all' }, secondary_btn: { text: 'Reject all', role: 'accept_necessary' // 'settings' or 'accept_necessary' } }, settings_modal: { title: 'Cookie preferences', save_settings_btn: 'Save settings', accept_all_btn: 'Accept all', reject_all_btn: 'Reject all', close_btn_label: 'Close', cookie_table_headers: [ {col1: 'Name'}, {col2: 'Domain'}, {col3: 'Expiration'}, {col4: 'Description'} ], blocks: [ { title: 'Cookie usage 📢', description: 'I use cookies to ensure the basic functionalities of the website and to enhance your online experience. You can choose for each category to opt-in/out whenever you want. For more details relative to cookies and other sensitive data, please read the full <a href="#" class="cc-link">privacy policy</a>.' }, { title: 'Strictly necessary cookies', description: 'These cookies are essential for the proper functioning of my website. Without these cookies, the website would not work properly', toggle: { value: 'necessary', enabled: true, readonly: true // cookie categories with readonly=true are all treated as "necessary cookies" } }, { title: 'Performance and Analytics cookies', description: 'These cookies allow the website to remember the choices you have made in the past', toggle: { value: 'analytics', // your cookie category enabled: false, readonly: false }, cookie_table: [ // list of all expected cookies { col1: '^_ga', // match all cookies starting with "_ga" col2: 'google.com', col3: '2 years', col4: 'description ...', is_regex: true }, { col1: '_gid', col2: 'google.com', col3: '1 day', col4: 'description ...', } ] }, { title: 'Advertisement and Targeting cookies', description: 'These cookies collect information about how you use the website, which pages you visited and which links you clicked on. All of the data is anonymized and cannot be used to identify you', toggle: { value: 'targeting', enabled: false, readonly: false } }, { title: 'More information', description: 'For any queries in relation to our policy on cookies and your choices, please <a class="cc-link" href="#yourcontactpage">contact us</a>.', } ] } } } });
-
-
As inline script
<body> <!-- body content ... --> <script defer src="<path-to-cookieconsent.js>"></script> <!-- Inline script --> <script> window.addEventListener('load', function(){ // obtain plugin var cc = initCookieConsent(); // run plugin with your configuration cc.run({ current_lang: 'en', autoclear_cookies: true, // default: false theme_css: '<path-to-cookieconsent.css>', // 🚨 replace with a valid path page_scripts: true, // default: false // delay: 0, // default: 0 // auto_language: '', // default: null; could also be 'browser' or 'document' // autorun: true, // default: true // force_consent: false, // default: false // hide_from_bots: false, // default: false // remove_cookie_tables: false // default: false // cookie_name: 'cc_cookie', // default: 'cc_cookie' // cookie_expiration: 182, // default: 182 (days) // cookie_domain: location.hostname, // default: current domain // cookie_path: '/', // default: root // cookie_same_site: 'Lax', // default: 'Lax' // use_rfc_cookie: false, // default: false // revision: 0, // default: 0 onAccept: function (cookie) { // ... }, onChange: function (cookie, changed_preferences) { // ... }, languages: { 'en': { consent_modal: { title: 'We use cookies!', description: 'Hi, this website uses essential cookies to ensure its proper operation and tracking cookies to understand how you interact with it. The latter will be set only after consent. <button type="button" data-cc="c-settings" class="cc-link">Let me choose</button>', primary_btn: { text: 'Accept all', role: 'accept_all' // 'accept_selected' or 'accept_all' }, secondary_btn: { text: 'Reject all', role: 'accept_necessary' // 'settings' or 'accept_necessary' } }, settings_modal: { title: 'Cookie preferences', save_settings_btn: 'Save settings', accept_all_btn: 'Accept all', reject_all_btn: 'Reject all', close_btn_label: 'Close', cookie_table_headers: [ {col1: 'Name'}, {col2: 'Domain'}, {col3: 'Expiration'}, {col4: 'Description'} ], blocks: [ { title: 'Cookie usage 📢', description: 'I use cookies to ensure the basic functionalities of the website and to enhance your online experience. You can choose for each category to opt-in/out whenever you want. For more details relative to cookies and other sensitive data, please read the full <a href="#" class="cc-link">privacy policy</a>.' }, { title: 'Strictly necessary cookies', description: 'These cookies are essential for the proper functioning of my website. Without these cookies, the website would not work properly', toggle: { value: 'necessary', enabled: true, readonly: true // cookie categories with readonly=true are all treated as "necessary cookies" } }, { title: 'Performance and Analytics cookies', description: 'These cookies allow the website to remember the choices you have made in the past', toggle: { value: 'analytics', // your cookie category enabled: false, readonly: false }, cookie_table: [ // list of all expected cookies { col1: '^_ga', // match all cookies starting with "_ga" col2: 'google.com', col3: '2 years', col4: 'description ...', is_regex: true }, { col1: '_gid', col2: 'google.com', col3: '1 day', col4: 'description ...', } ] }, { title: 'Advertisement and Targeting cookies', description: 'These cookies collect information about how you use the website, which pages you visited and which links you clicked on. All of the data is anonymized and cannot be used to identify you', toggle: { value: 'targeting', enabled: false, readonly: false } }, { title: 'More information', description: 'For any queries in relation to our policy on cookies and your choices, please <a class="cc-link" href="#yourcontactpage">contact us</a>.', } ] } } } }); }); </script> <body>
-
You can change the color scheme with css variables inside cookieconsent.css. You can also change some basic layout options via the gui_options
inside the config. object; example:
cookieconsent.run({
// ...
gui_options: {
consent_modal: {
layout: 'cloud', // box/cloud/bar
position: 'bottom center', // bottom/middle/top + left/right/center
transition: 'slide' // zoom/slide
},
settings_modal: {
layout: 'box', // box/bar
// position: 'left', // left/right
transition: 'slide' // zoom/slide
}
}
//...
});
Default layout is box
and default transition is zoom
.
You can easily manage third party scripts (enable/disable based on user's preferences) via the page_scripts
option:
-
Enable page scripts management:
cookieconsent.run({ // ... page_scripts: true // ... });
-
Set
type="text/plain"
anddata-cookiecategory="<category>"
to anyscript
tag you want to manage:<script type="text/plain" data-cookiecategory="analytics" src="analytics.js" defer></script>
Note:
data-cookiecategory
must be a valid category defined inside the configuration object
After getting the plugin like so:
var cookieconsent = initCookieConsent();
the following methods are available:
- cookieconsent
.run(<config_object>)
- cookieconsent
.show(<optional_delay>)
- cookieconsent
.hide()
- cookieconsent
.showSettings(<optional_delay>)
- cookieconsent
.hideSettings()
Additional methods for an easier management of your scripts and cookie settings (expand them to see usage example):
-
cookieconsent
.accept(<accepted_categories>, <optional_rejected_categories>)
[v2.5.0+]- accepted_categories:
string
orstring[]
- rejected_categories:
string[]
- optional
Note: all categories marked as
readonly
will ALWAYS be enabled/accepted regardless of the categories provided inside the.accept()
API call.Examples:
cookieconsent.accept('all'); // accept all categories cookieconsent.accept([]); // accept none (reject all) cookieconsent.accept('analytics'); // accept only analytics category cookieconsent.accept(['cat_1', 'cat_2']); // accept only these 2 categories cookieconsent.accept(); // accept all currently selected categories inside modal cookieconsent.accept('all', ['analytics']); // accept all except "analytics" category cookieconsent.accept('all', ['cat_1', 'cat_2']); // accept all except these 2 categories
How to later reject a specific category (cookieconsent already accepted)? Same as above:
cookieconsent.accept('all', ['targeting']); // opt out of targeting category
- accepted_categories:
-
cookieconsent
.allowedCategory(<category_name>)
Note: there are no default cookie categories, you create them!
A cookie category corresponds to the string of the
value
property inside thetoggle
object:// ... toggle: { value: 'analytics', // cookie category enabled: false, // default status readonly: false // allow to enable/disable // reload: 'on_disable', // allows to reload page when the current cookie category is deselected } // ...
Example:
// Check if user accepts cookie consent with analytics category enabled if (!cookieconsent.allowedCategory('analytics')) { // yoo, you might want to load analytics.js ... };
-
cookieconsent
.validCookie(<cookie_name>)
If cookie exists and has non empty (
''
) value => returntrue
, otherwisefalse
.// Example: check if '_gid' cookie is set if (!cookieconsent.validCookie('_gid')) { // yoo, _gid cookie is not set, do something ... };
-
cookieconsent
.eraseCookies(<cookie_names>, <optional_path>, <optional_domains>)
[v2.5.0+]- cookie_names:
string[]
- path:
string
- optional - domains:
string[]
- optional
Examples:
cookieconsent.eraseCookies(['cc_cookies']); // erase "cc_cookie" if it exists cookieconsent.eraseCookies(['cookie1', 'cookie2']); // erase these 2 cookies cookieconsent.eraseCookies(['cc_cookie'], "/demo"); cookieconsent.eraseCookies(['cc_cookie'], "/demo", [location.hostname]);
- cookie_names:
-
cookieconsent
.loadScript(<path>, <callback_function>, <optional_custom_attributes>)
Basic example:
cookieconsent.loadScript('https://www.google-analytics.com/analytics.js', function(){ // Script loaded, do something });
How to load scripts with custom attributes:
cookieconsent.loadScript('https://www.google-analytics.com/analytics.js', function(){ // Script loaded, do something }, [ {name: 'id', value: 'ga_id'}, {name: 'another-attribute', value: 'value'} ]);
-
cookieconsent
.set(<field>, <object>)
[v2.6.0+]The
.set()
method allows you to set the following values:- data (used to save custom data inside the plugin's cookie)
- revision
How to save custom
data
:// Set cookie's "data" field to whatever the value of the `value` prop. is cookieconsent.set('data', {value: {id: 21, country: "italy"}}); // Only add/update the specified props. cookieconsent.set('data', {value: {id: 22, new_prop: 'new prop value'}, mode: 'update'});
How to enforce/set a new
revision
:// Update revision to the new value (without prompting the user) cookieconsent.set('revision', {value: 2}); // Update revision to the new value (ask consent before setting the new revision) cookieconsent.set('revision', {value: 2, prompt_consent: true});
-
cookieconsent
.get(<field>)
[v2.6.0+]The
.get()
method allows you to retrieve any of the fields inside the plugin's cookie:cookieconsent.get('level'); // retrieve all accepted categories (if cookie exists) cookieconsent.get('data'); // retrieve custom data (if cookie exists) cookieconsent.get('revision'); // retrieve revision number (if cookie exists)
-
cookieconsent
.getConfig(<field>)
[v2.7.0+]The
.getConfig()
method allows you to read configuration options from the current instance:cookieconsent.getConfig('current_lang'); // get currently used language cookieconsent.getConfig('cookie_expiration'); // get configured cookie expiration // ...
Below a table which sums up all of the available options (must be passed to the .run() method).
Option | Type | Default | Description |
---|---|---|---|
autorun |
boolean | true | If enabled, show the cookie consent as soon as possible (otherwise you need to manually call the .show() method) |
delay |
number | 0 | Number of milliseconds before showing the consent-modal |
cookie_expiration |
number | 182 | Number of days before the cookie expires (182 days = 6 months) |
cookie_path |
string | "/" | Path where the cookie will be set |
cookie_domain |
string | location.hostname | Specify your domain (will be grabbed by default) or a subdomain |
cookie_same_site |
string | "Lax" | SameSite attribute |
use_rfc_cookie |
boolean | false | Enable if you want the value of the cookie to be rfc compliant |
theme_css |
string | - | Specify path to the .css file |
force_consent |
boolean | false | Enable if you want to block page navigation until user action (check faq for a proper implementation) |
revision |
number | 0 | Specify this option to enable revisions. Check below for a proper usage |
current_lang |
string | - | Specify one of the languages you have defined (can also be dynamic): 'en' , 'de' ... |
auto_language |
string | null | Language auto-detection strategy. Null to disable (default), "browser" to get user's browser language or "document" to read value from <html lang="..."> of current page. If language is not defined => use specified current_lang |
autoclear_cookies |
boolean | false | Enable if you want to automatically delete cookies when user opts-out of a specific category inside cookie settings |
page_scripts |
boolean | false | Enable if you want to easily manage existing <script> tags. Check manage third party scripts |
remove_cookie_tables |
boolean | false | Enable if you want to remove the html cookie tables (but still want to make use of autoclear_cookies ) |
hide_from_bots |
boolean | false | Enable if you don't want the plugin to run when a bot/crawler/webdriver is detected |
gui_options |
object | - | Customization option which allows to choose layout, position and transition. Check layout options & customization |
onAccept |
function | - | Method run once either when: 1. The moment the cookie consent is accepted 2. After each page load (if cookie consent has already been accepted) |
onChange |
function | - | Method run whenever preferences are modified (and only if cookie consent has already been accepted) |
languages |
object | - | Check below for configuration |
-
Configuration with gtag.js - Google Analytics
- enable
page_scripts
- set
type="text/plain"
anddata-cookiecategory="<your-category>"
to each script:
<!-- Global site tag (gtag.js) - Google Analytics --> <script type="text/plain" data-cookiecategory="analytics" async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script> <script type="text/plain" data-cookiecategory="analytics"> window.dataLayer = window.dataLayer || []; function gtag(){window.dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'GA_MEASUREMENT_ID'); </script> <script defer src="<path-to-cookieconsent.js>"></script> <script> window.addEventListener('load', function () { // obtain cookieconsent plugin var cookieconsent = initCookieConsent(); // run plugin with config object cookieconsent.run({ autorun: true, current_lang: 'en', theme_css: '<path-to-cookieconsent.css>', autoclear_cookies: true, page_scripts: true, onAccept: function (cookie) { // ... cookieconsent accepted }, onChange: function (cookie, changed_preferences) { // ... cookieconsent preferences were changed }, languages: { en: { consent_modal: { title: 'I use cookies', description: 'Hi, this website uses essential cookies to ensure its proper operation and tracking cookies to understand how you interact with it. The latter will be set only upon approval. <a aria-label="Cookie policy" class="cc-link" href="#">Read more</a>', primary_btn: { text: 'Accept', role: 'accept_all' // 'accept_selected' or 'accept_all' }, secondary_btn: { text: 'Settings', role: 'settings' // 'settings' or 'accept_necessary' } }, settings_modal: { title: 'Cookie preferences', save_settings_btn: 'Save settings', accept_all_btn: 'Accept all', reject_all_btn: 'Reject all', // optional, [v.2.5.0 +] cookie_table_headers: [ {col1: 'Name'}, {col2: 'Domain'}, {col3: 'Expiration'}, {col4: 'Description'}, {col5: 'Type'} ], blocks: [ { title: 'Cookie usage', description: 'I use cookies to ensure the basic functionalities of the website and to enhance your online experience. You can choose for each category to opt-in/out whenever you want.' }, { title: 'Strictly necessary cookies', description: 'These cookies are essential for the proper functioning of my website. Without these cookies, the website would not work properly.', toggle: { value: 'necessary', enabled: true, readonly: true } }, { title: 'Analytics cookies', description: 'These cookies collect information about how you use the website, which pages you visited and which links you clicked on. All of the data is anonymized and cannot be used to identify you.', toggle: { value: 'analytics', enabled: false, readonly: false }, cookie_table: [ { col1: '^_ga', col2: 'google.com', col3: '2 years', col4: 'description ...', col5: 'Permanent cookie', is_regex: true }, { col1: '_gid', col2: 'google.com', col3: '1 day', col4: 'description ...', col5: 'Permanent cookie' } ] }, { title: 'More information', description: 'For any queries in relation to my policy on cookies and your choices, please <a class="cc-link" href="#yourwebsite">contact me</a>.', } ] } } } }); }); </script>
- enable
-
More to be added ...
Languages is an object which basically holds all of the text/html of your cookie modals in different languages. In here you can define cookie categories
, cookie tables
, opt-in/out toggle
for each category and more. For each language, a consent_modal
object and a settings_modal
object must be configured.
Example with multiple languages ('en' and 'it')
cookieconsent.run({
// ...,
languages: {
'en': {
consent_modal: {
title: 'Title here ...',
description: 'Description here ...',
primary_btn: {
text: 'Accept',
role: 'accept_all' // 'accept_selected' or 'accept_all'
},
secondary_btn: {
text: 'Settings',
role: 'settings' // 'settings' or 'accept_necessary'
}
},
settings_modal: {
title: 'Cookie preferences ...',
save_settings_btn: 'Save settings',
accept_all_btn: 'Accept all',
blocks: [
{
title: 'First block title ...',
description: 'First block description ...'
}, {
title: 'Second block title ...',
description: 'Second block description ...',
toggle: {
value: 'my_category1',
enabled: true,
readonly: true
}
}, {
title: 'Third block title ...',
description: 'Third block description ...',
toggle: {
value: 'my_category2',
enabled: false,
readonly: false
}
}
]
}
},
'it': {
consent_modal: {
title: 'Title in italian here ...',
description: 'Description in italian here ...',
primary_btn: {
text: 'Accept in italian',
role: 'accept_all' //'accept_selected' or 'accept_all'
},
secondary_btn: {
text: 'Settings',
role: 'settings' //'settings' or 'accept_necessary'
}
},
settings_modal: {
title: 'Cookie preferences ...',
save_settings_btn: 'Save settings in italian',
accept_all_btn: "Accept all",
blocks: [
{
title: 'First block title in italian ...',
description: 'First block description in italian ...'
}, {
title: 'Second block title in italian ...',
description: 'Second block description in italian...',
toggle: {
value: 'my_category1',
enabled: true,
readonly: true
}
}, {
title: 'Third block title in italian ...',
description: 'Third block description in italian...',
toggle: {
value: 'my_category2',
enabled: false,
readonly: false
}
}
]
}
}
}
});
Example with custom cookie table
You can create tables with a custom number of columns to explain what each cookie does.
NOTE: If you want to also use autoclear_cookie
, make sure the first column of the cookie table contains the name of the cookie.
Check demo app.js which has a full example with cookie table.
Note:
- default revision number is 0
- if existing revision number is different from the one you just specified => show consent modal
-
Enable revisions by specifying a valid
revision
parameter:cookieconsent.run({ // ..., revision: 1, // ... })
-
Set a valid
revision_message
parameter (optional) insideconsent_modal
, and add the following placeholder{{revision_message}}
insidedescription
:cookieconsent.run({ // ..., revision: 1, // ..., languages: { en: { consent_modal: { // ..., description: 'Usual description ... {{revision_message}}', revision_message: '<br> Dude, my terms have changed. Sorry for bothering you again!', // ... }, // ... } } // ... })
-
How to enable dark-mode
Either manually add the following class
c_darkmode
to the body/html tag, or toggle it via javascript:document.body.classList.toggle('c_darkmode');
-
How to add link/button to open cookie settings
Create a link (or button) with
data-cc="c-settings"
attribute:<a href="javascript:void(0);" aria-label="View cookie settings" data-cc="c-settings">Cookie Settings</a>
-
How to integrate with my multi-language website
If you have multiple versions of your html page, each with a different <html lang="..." > attribute, you can grab this value using:
document.documentElement.getAttribute('lang');
and then set it as
current_lang
value like this:cookieconsent.run({ // ... current_lang: document.documentElement.getAttribute('lang'), // ... });
Note: make sure that the lang attribute's value format (example: 'en' => 2 characters) is identical to the ones you defined. If you have 'en-US' as lang attribute, make sure to also specify 'en-US' (and not just 'en') in the config. parameters.
-
How to load scripts after a specific cookie category has been accepted
Suppose you have a
analytics.js
file you want to load after theanalytics
category has been accepted:-
Method 1 (recommended)
-
enable
page_scripts
:cookieconsent.run({ // ... page_scripts: true, // ... });
-
add a
<script>
tag with the following attributes:type="text/plain"
anddata-cookiecategory="<category>"
<script type="text/plain" data-cookiecategory="analytics" src="<path-to-analytics.js>"></script>
-
-
Method 2
Load script using the
.loadScript()
method inside theonAccept
method:cookieconsent.run({ // ... onAccept: function () { if (cookieconsent.allowedCategory('analytics')) { cookieconsent.loadScript('<path-to-analytics.js', function () { // script loaded ... }); } } })
-
-
How to autoload the .css file
You need to set
theme_css
to a valid path.cookieconsent.run({ // ... theme_css: '../src/cookieconsent.css', // ... });
-
Make consent required (block page navigation until action)
This is a css only solution:
- enable
force_consent
option:cookieconsent.run({ // ... force_consent: true, // ... });
- That should do it. If you want to remove the weird horizontal jump (due to the scrollbar disappearing) you can add the following style inside the head tag of your page:
<style> html, body { height: auto!important; width: 100vw!important; overflow-x: hidden!important; } </style>
For a full example check the second demo.
- enable
-
How to create custom cookie tables
- Cookie tables are defined by you, that is you choose how many columns and what their naming will be
- Make sure that the first column of the table contains the name of the cookie for
autoclear_cookie
to work properly
-
Specify the table structure via the
cookie_table_headers
property insidesettings_modal
object:Example with 3 columns:
// ... cookie_table_headers: [ {col1: "Name"}, {col2: "Source"}, {col3: "Description"}, ] // ...
-
Now you can create a
cookie_table
array of objects:// ... cookie_table: [ { col1: '_ga', col2: 'google.com', col3: 'description ..', }, { col1: '_gid', col2: 'google.com', col3: 'description ..', } ] // ...
Check the examples above for a valid implementation.
-
How to use in React
-
Create a new component:
CookieConsent.js
import { useEffect } from "react"; import "./<path-to-cookieconsent.css>"; import "./<path-to-cookieconsent.js>"; export default function CookieConsent() { useEffect(() => { const cc = window.initCookieConsent(); cc.run({ // your config }); }, []); return null; }
-
Import the component only once (generally in your main/root component like
App.js
orindex.js
)import CookieConsent from "./<path-to-CookieConsent.js-component>"; export default function App() { return ( <div className="App"> <h1>Hello World</h1> <CookieConsent/> </div> ); }
-
Distributed under the MIT License. See LICENSE for more information.