@bato-web-agency/cookie-consent
v1.2.3
Published
JavaScript cookie consent banner with customizable UI, i18n, configurable script loading, and runtime APIs.
Maintainers
Readme
Cookie Consent
JavaScript cookie consent banner with customizable UI, local storage, i18n, configurable script loading, and runtime APIs.
Install
npm install @bato-web-agency/cookie-consentQuick Start
import CookieConsent from '@bato-web-agency/cookie-consent';
import '@bato-web-agency/cookie-consent/style.css';
await CookieConsent.init({
mode: 'gdpr',
policyVersion: '2026-05-19',
language: 'browser',
fallbackLanguage: 'en',
layout: 'floating',
policyLinks: [{ label: 'Cookie policy', href: '/cookie-policy' }],
scripts: [
{
id: 'analytics',
category: 'analytics',
callback: () => {
window.analyticsLoaded = true;
}
}
]
});Browser Script
When you serve the built package files yourself, use the UMD build and compiled CSS:
<link rel="stylesheet" href="/dist/style.css" />
<script src="/dist/index.umd.js"></script>
<script>
window.CookieConsent.init({
defaultLanguage: 'uk',
policyVersion: '1'
});
</script>For CDN usage with jsDelivr:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@bato-web-agency/[email protected]/style.css"
/>
<script src="https://cdn.jsdelivr.net/npm/@bato-web-agency/[email protected]"></script>
<script>
window.CookieConsent.init({
defaultLanguage: 'uk',
policyVersion: '1'
});
</script>For CDN usage with unpkg:
<link
rel="stylesheet"
href="https://unpkg.com/@bato-web-agency/[email protected]/dist/style.css"
/>
<script src="https://unpkg.com/@bato-web-agency/[email protected]/dist/index.umd.js"></script>
<script>
window.CookieConsent.init({
defaultLanguage: 'uk',
policyVersion: '1'
});
</script>The /dist/... paths above are local/static hosting paths, not CDN URLs. Examples and plain HTML templates inside this repository should use the built files:
<link rel="stylesheet" href="./dist/style.css" />
<script type="module">
import CookieConsent from './dist/index.es.js';
</script>For source-level development, edit src/styles/index.scss and run npm run build.
Runtime API
CookieConsent.init(config)CookieConsent.getConsent()CookieConsent.hasConsent(category)CookieConsent.setConsent({ categories })CookieConsent.acceptCategory(category)CookieConsent.resetConsent()CookieConsent.openBanner()CookieConsent.openPreferences()CookieConsent.close()CookieConsent.on(event, handler)CookieConsent.off(event, handler)CookieConsent.registerScript(script)CookieConsent.loadCategory(category)CookieConsent.registerEmbed(embed)CookieConsent.loadEmbed(id)CookieConsent.loadEmbedsByCategory(category)
Use getConsent() and hasConsent(category) from arbitrary site JavaScript to branch behaviour after the user choice:
if (CookieConsent.hasConsent('analytics')) {
window.siteAnalyticsFeatureEnabled = true;
}Consent Mode
mode controls when tagged scripts are loaded:
gdpris the default. Registered scripts and blocked script selectors are loaded only after the user accepts the required category.eprivacyloads registered scripts and blocked script selectors automatically after initialization or registration.
CookieConsent.init({
mode: 'eprivacy',
scripts: [
{
id: 'analytics',
category: 'analytics',
selector: 'script[type="text/plain"][data-cookie-category="analytics"]'
}
]
});In eprivacy mode, automatic script loading does not mark optional categories as accepted. Use getConsent() and hasConsent(category) for the user's saved preference state.
YouTube And Vimeo Embeds
Embedded videos are managed separately from JavaScript scripts because YouTube and Vimeo cookies can be created when an iframe loads. Use data-cc-src, not src, for compliance-safe markup in gdpr mode:
<div
data-cc-embed="youtube"
data-cc-id="homepage-video"
data-cc-src="https://www.youtube.com/watch?v=VIDEO_ID"
data-cc-title="Product video"
></div>CookieConsent.init({
mode: 'gdpr',
embeds: {
enabled: true,
category: 'marketing',
autoScan: true,
providers: {
youtube: {
enabled: true,
privacyMode: true
},
vimeo: {
enabled: true,
dnt: true
}
}
}
});In gdpr, the library renders a local placeholder until the user allows the configured category. In eprivacy, embeds load automatically with privacy-friendly URL normalization. YouTube URLs are converted to youtube-nocookie.com when privacyMode is enabled, and Vimeo URLs receive dnt=1 when dnt is enabled.
Regular <iframe src="..."> markup can load before the consent library runs, so use data-cc-src or config-based embeds instead.
Customization
Use CSS variables for fast styling:
:root {
--cc-font-size: 1rem;
--cc-color-primary: #0f6cbd;
--cc-color-primary-hover: #115ea3;
--cc-color-primary-active: #0f548c;
--cc-color-secondary: #f5f5f5;
--cc-color-focus: #000;
--cc-duration: 160ms;
--cc-easing: cubic-bezier(0.33, 0, 0.67, 1);
--cc-font-family: 'Segoe UI', 'Segoe UI Variable', system-ui, sans-serif;
--cc-radius: 4px;
--cc-shadow: 0 0.5em 1em rgb(0 0 0 / 14%), 0 0 0.125em rgb(0 0 0 / 12%);
}Animations are controlled by --cc-duration and respect prefers-reduced-motion.
Hide UI parts through components. The logo is included in this list:
CookieConsent.init({
components: {
logo: false
}
});Supported starter languages: en, en-gb, en-uk, de, fr, es, ca-es, it, sv, no, nl, pt, fi, hu, cs, hr, da, sk, sl, pl, el, he, mk, uk, ro, sr, et, lt, lv, ru, bg, cy, ja, ar, and tr.
Built-in language copy is stored as one JSON file per locale in src/i18n/locales.
Every label can be overridden with translations.
Language resolution is controlled by language:
browserusesnavigator.languageand is the default.autouses the site language from the root<html lang="...">attribute.- any language code, for example
heoren-uk, forces that language.
Category content supports a short description and expandable details text. Override details through content or translations; category config is for category metadata such as title, description, required, and defaultValue.
CookieConsent.init({
content: {
en: {
embeds: {
placeholder: {
title: 'Video content',
description: 'Allow marketing cookies to play this video.',
buttonText: 'Allow and play'
}
},
categories: {
analytics: {
description: 'Short analytics summary.',
details: 'Long analytics explanation shown after clicking Read More.'
}
}
}
}
});Editable popup text supports safe inline formatting such as links and emphasis:
CookieConsent.init({
providedBy: 'Provided by <a href="https://bato.dev">Bato Web Agency</a>',
content: {
en: {
banner: {
description: 'We use <strong>cookies</strong> to improve the site.'
}
}
}
});Formatted text allows these tags: a, abbr, b, br, code, em, i, mark, small, span, strong, sub, sup, and u. Supported attributes are href, target, rel, and title on links; title on abbr; and class or title on span.
The packaged stylesheet is available as compiled CSS and a source SCSS entrypoint:
import '@bato-web-agency/cookie-consent/style.css';
import '@bato-web-agency/cookie-consent/style.scss';The SCSS source is split into internal partial files for maintenance, but @bato-web-agency/cookie-consent/style.scss is the public SCSS import path.
See docs/API.md and docs/CONFIGURATION.md for the full configuration reference.
