npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bato-web-agency/cookie-consent

v1.2.3

Published

JavaScript cookie consent banner with customizable UI, i18n, configurable script loading, and runtime APIs.

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-consent

Quick 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:

  • gdpr is the default. Registered scripts and blocked script selectors are loaded only after the user accepts the required category.
  • eprivacy loads 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:

  • browser uses navigator.language and is the default.
  • auto uses the site language from the root <html lang="..."> attribute.
  • any language code, for example he or en-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.