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

@meui-creative/cookies

v4.0.0

Published

GDPR-compliant cookie consent management for React with centralized Payload CMS configuration

Downloads

101

Readme

@meui-creative/cookies

GDPR-compliant cookie consent management for React and Next.js with 5 unique preset layouts, remote configuration, and full Google Consent Mode V2 support.

Features

  • 5 Unique Layouts - From minimal bars to full sidebars, find the perfect design
  • 🎨 Fully Customizable - Override colors, position, and styles for each preset
  • 🌍 Multi-language - Built-in translations (EN, CS, DE) with auto-detection
  • 📡 Remote Config - Centralized content management via Payload CMS
  • 🎯 Google Consent Mode V2 - Full automatic support with all required parameters
  • 🔌 Service Integrations - Optional auto-init for Google Analytics, Facebook Pixel, GTM, and more
  • 🚫 Script Blocking - Automatically blocks scripts until consent
  • 💪 Robust Positioning - React Portal ensures banner always displays correctly
  • Accessible - Full keyboard navigation and ARIA support
  • 📱 Responsive - Mobile-first design
  • 🎯 TypeScript - Full type safety
  • GDPR Compliant - Strict mode blocks all non-essential cookies

Installation

npm install @meui-creative/cookies framer-motion lucide-react

⚠️ Important for Google Analytics/GTM users

If you have existing Google tags in your <head>, remove them and use the plugin integration instead:

// ❌ Wrong - custom tag without Consent Mode
<script async src="https://www.googletagmanager.com/gtag/js?id=GA-XXX"></script>

// ✅ Correct - use plugin integration
<CookieConsent
  integrations={{
    googleAnalytics: 'GA-XXX'
  }}
/>

The plugin ensures proper order: consent default → load tag → config → update.

Quick Start

1. Add to your layout

import { CookieConsent } from '@meui-creative/cookies'

export default function App() {
  return (
    <>
      <CookieConsent />
      {/* Your app */}
    </>
  )
}

2. Choose your integration method

You have two options for integrating analytics and tracking services:


✅ Method A: Integrated (Recommended)

Best for: Google Analytics, GTM, Facebook Pixel, Hotjar, Clarity

Simply pass your IDs via the integrations prop. The library handles everything automatically, including Google Consent Mode V2.

<CookieConsent
  integrations={{
    googleAnalytics: process.env.NEXT_PUBLIC_GA_ID,
    googleTagManager: process.env.NEXT_PUBLIC_GTM_ID,
    facebookPixel: process.env.NEXT_PUBLIC_FB_PIXEL_ID,
    hotjar: process.env.NEXT_PUBLIC_HOTJAR_ID,
    clarity: process.env.NEXT_PUBLIC_CLARITY_ID,
  }}
/>

How it works:

  1. Plugin automatically sets gtag('consent', 'default', ...) with denied for all parameters
  2. Creates tracking scripts dynamically after user consents
  3. Calls gtag('consent', 'update', ...) when user accepts/declines
  4. Scripts load only when user accepts the relevant category
  5. Works automatically on every page load (consent is saved)

Category mapping:

  • googleAnalytics → analytics
  • googleTagManager → analytics
  • facebookPixel → marketing
  • hotjar → analytics
  • clarity → analytics

📝 Method B: Manual blocking

Best for: Custom scripts, third-party widgets, or services not supported by integrations

Add these two attributes to your existing script tags:

  • type="text/plain" - Prevents script from executing
  • data-cookie-category="..." - Specifies which category

Examples:

<!-- Google Analytics → analytics -->
<script type="text/plain" data-cookie-category="analytics">
  gtag('config', 'GA-XXXXXXXXX');
</script>

<!-- Facebook Pixel → marketing -->
<script type="text/plain" data-cookie-category="marketing">
  fbq('init', 'YOUR_PIXEL_ID');
  fbq('track', 'PageView');
</script>

<!-- Custom tracking → analytics -->
<script type="text/plain" data-cookie-category="analytics">
  // Your custom tracking code
</script>

<!-- YouTube embed → marketing -->
<iframe data-cookie-category="marketing" src="https://www.youtube.com/embed/VIDEO_ID"> </iframe>

Available categories:

  • strictly-necessary - Always allowed (use rarely)
  • functional - Site functionality
  • analytics - Google Analytics, Hotjar, Clarity, GTM
  • marketing - Facebook Pixel, ads, YouTube embeds

Google Consent Mode V2

Plugin automatically supports Google Consent Mode V2 according to official documentation.

What it does automatically

✅ Sets gtag('consent', 'default', ...) with denied for all parameters before loading Google tags
✅ Calls gtag('consent', 'update', ...) after user clicks Accept/Decline
✅ Supports all V2 parameters: ad_storage, analytics_storage, ad_user_data, ad_personalization
✅ Enables URL passthrough for ad click tracking without cookies
✅ Enables ads data redaction for GDPR compliance

Basic usage

<CookieConsent
  integrations={{
    googleAnalytics: 'GA-XXXXXXXXX',
    googleTagManager: 'GTM-XXXXXX',
  }}
/>

That's it! Consent Mode V2 works automatically.

Category mapping to Consent Mode

| Plugin category | Consent Mode parameters | | -------------------- | -------------------------------------------------- | | marketing | ad_storage, ad_user_data, ad_personalization | | analytics | analytics_storage | | functional | functionality_storage, personalization_storage | | strictly-necessary | security_storage (always granted) |

Testing in GTM

  1. Open GTM → Preview Mode
  2. Load your website
  3. Click "Consent" tab in Preview window

Before Accept:

  • On-page default: Denied
  • Current state: Denied

After Accept:

  • On-page update: Granted
  • Current state: Granted

Debug in console

// Show all consent events
window.dataLayer.filter(e => e[0] === 'consent')

// Expected output:
[
  ['consent', 'default', { ad_storage: 'denied', ... }],
  ['consent', 'update', { ad_storage: 'granted', ... }]
]

Advanced usage

import { CookieConsent, initConsentMode, updateConsentMode } from '@meui-creative/cookies'

// Region-specific consent
initConsentMode({
  region: ['ES', 'DE', 'FR'], // EU only
  urlPassthrough: true,
  adsDataRedaction: true,
})

// Manual consent update
updateConsentMode({
  analytics: true,
  marketing: false,
})

Full documentation

For detailed guide, see the Consent Mode V2 documentation:

  • How it works under the hood
  • Migration guide from v1.x
  • Troubleshooting common issues
  • API reference
  • Testing examples

Design Presets

Choose from 5 professionally designed layouts, each with unique UX:

default - Classic Card

Color: Blue (#3b82f6) | Position: Bottom-left

Clean, professional design with large cookie icon. Perfect for corporate websites.

<CookieConsent />

meui - Compact with Inline Settings

Color: Green (#4A6953) | Position: Bottom-left

Original Meui design with expandable settings directly in banner. Saves modal interactions.

<CookieConsent preset="meui" />

minimal - Bottom Bar

Color: Black (#000) | Position: Full-width bottom

Horizontal bar spanning full width. Non-intrusive, great for blogs and content sites.

<CookieConsent preset="minimal" />

card - Accent Header

Color: Violet (#8b5cf6) | Position: Bottom-right

Modern card with colored header stripe and shield icon. Bold and eye-catching.

<CookieConsent preset="card" />

sidebar - Full-Height Panel

Color: Emerald (#10b981) | Position: Right sidebar

Full-height sidebar with detailed information and trust indicators. Best for complex consent needs.

<CookieConsent preset="sidebar" />

Customization

Every preset can be customized. Override color, position, language, or any style property:

Change Color

<CookieConsent
  preset="default"
  accentColor="#ec4899" // Pink
/>

Change Position

<CookieConsent
  preset="card"
  style={{
    position: 'top-center', // Move to top
  }}
/>

Change Language

<CookieConsent
  preset="meui"
  language="cs" // Czech
/>

Multiple Overrides

<CookieConsent
  preset="minimal"
  accentColor="#f97316"
  language="de"
  style={{
    position: 'top-center',
    animation: {
      direction: 'down',
      duration: 0.5,
    },
  }}
/>

Configuration

Basic Setup (GDPR Compliant)

<CookieConsent
  preset="default"
  language="cs"
  links={{
    privacyPolicy: '/privacy',
    cookiePolicy: '/cookies',
  }}
/>

With Analytics

<CookieConsent
  preset="card"
  language="en"
  links={{
    privacyPolicy: '/privacy',
    cookiePolicy: '/cookies',
  }}
  integrations={{
    googleAnalytics: 'GA-XXXXXXXXX',
  }}
/>

Custom Position & Color

<CookieConsent
  preset="sidebar"
  accentColor="#10b981"
  style={{
    position: 'bottom-left', // Sidebar on left instead of right
  }}
  links={{
    privacyPolicy: '/privacy',
    cookiePolicy: '/cookies',
  }}
/>

All Configuration Options

<CookieConsent
  // Design
  preset="default" // 'default' | 'meui' | 'minimal' | 'card' | 'sidebar'
  accentColor="#3b82f6" // Any hex color
  borderRadius="rounded" // 'rounded' | 'sharp'
  // Position & Layout
  style={{
    position: 'bottom-left', // 'bottom-left' | 'bottom-center' | 'bottom-right'
    // 'top-left' | 'top-center' | 'top-right'
    animation: {
      direction: 'up', // 'up' | 'down' | 'left' | 'right' | 'fade'
      duration: 0.3, // Animation duration in seconds
      enabled: true, // Enable/disable animations
    },
  }}
  // Content & Language
  language="en" // 'en' | 'cs' | 'de'
  descriptionMode="short" // 'short' | 'long'
  // Behavior
  mode="strict" // 'strict' (GDPR) | 'soft' (informational)
  showSettingsButton={true} // Show settings button
  closeButton={true} // Show close button
  showRejectLink={true} // Show reject link
  ttl={365} // Consent validity in days
  // Legal (Required for GDPR)
  links={{
    privacyPolicy: '/privacy',
    cookiePolicy: '/cookies',
  }}
  // Integrations (with automatic Consent Mode V2)
  integrations={{
    googleAnalytics: 'GA-XXXXXXXXX',
    facebookPixel: '123456789',
    googleTagManager: 'GTM-XXXXXX',
    hotjar: 'XXXXXX',
    clarity: 'XXXXXX',
  }}
  // Callbacks
  onAccept={choices => console.log('Accepted:', choices)}
  onDecline={() => console.log('Declined')}
  onChange={choices => console.log('Changed:', choices)}
  onReady={() => console.log('Ready')}
  // Advanced
  domain="example.com" // For subdomain consent
  debug={false} // Enable debug logging
/>

Position Options

All presets support 6 positions:

  • bottom-left - Bottom left corner
  • bottom-center - Bottom center
  • bottom-right - Bottom right corner
  • top-left - Top left corner
  • top-center - Top center
  • top-right - Top right corner

Note: minimal preset adapts to top/bottom (full-width bar)
Note: sidebar preset uses left/right from position (full-height panel)


Manual Control

Show Settings

import { showCookieSettings } from '@meui-creative/cookies'

export function Footer() {
  return <button onClick={showCookieSettings}>Cookie Settings</button>
}

Revoke Consent

import { revokeConsent } from '@meui-creative/cookies'

function clearConsent() {
  revokeConsent()
}

Export User Data (GDPR)

Export all stored consent data for GDPR data access requests:

import { exportConsent } from '@meui-creative/cookies'

function downloadUserData() {
  const data = exportConsent()

  if (!data) {
    console.log('No consent data found')
    return
  }

  // Returns ConsentRecord:
  // {
  //   version: "1.0.0",
  //   timestamp: 1730000000000,
  //   choices: { analytics: true, marketing: false, ... },
  //   userAgent: "Mozilla/5.0...",
  //   language: "cs"
  // }

  // Download as JSON
  const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `cookie-consent-${Date.now()}.json`
  a.click()
  URL.revokeObjectURL(url)
}

What data is stored:

  • localStorage (meui_cookie_consent): Full consent record with all metadata
  • Cookie (meui_cookie_consent): Simplified comma-separated list of accepted categories (for server-side access)

Data retention:

  • Data expires after TTL (default 365 days)
  • Automatically cleared on version change
  • Can be manually revoked with revokeConsent()

Headless Mode

Use the hook directly for custom UI:

import { useCookieConsent } from '@meui-creative/cookies'

export function CustomCookieBanner() {
  const { consent, hasConsent, isReady, categories, acceptAll, declineAll } = useCookieConsent({
    preset: 'default',
    links: {
      privacyPolicy: '/privacy',
      cookiePolicy: '/cookies',
    },
  })

  if (!isReady || hasConsent) return null

  return (
    <div className="my-custom-banner">
      <h2>We use cookies</h2>
      <button onClick={acceptAll}>Accept All</button>
      <button onClick={declineAll}>Decline</button>
    </div>
  )
}

Remote Configuration

1. Install Payload Plugin

// payload.config.ts
import { cookieConsentPlugin } from '@meui-creative/cookies/payload'

export default buildConfig({
  plugins: [
    cookieConsentPlugin({
      enabled: true,
      defaultVersion: '1.0.0',
    }),
  ],
})

2. Use in Frontend

<CookieConsent
  preset="default"
  apiUrl="https://your-cms.com/api/cookie-config"
  links={{
    privacyPolicy: '/privacy',
    cookiePolicy: '/cookies',
  }}
/>

Remote config updates texts and categories. Style configuration remains local.


EU Legal Requirements

⚠️ Required for GDPR Compliance

1. Strict Mode

mode = 'strict' // Blocks cookies before consent

2. Legal Links

links={{
  privacyPolicy: '/privacy',    // Required
  cookiePolicy: '/cookies'      // Required
}}

3. Easy Reject

showSettingsButton={true}       // Allow granular control
showRejectLink={true}           // Easy rejection

✅ Best Practices

  • Use 6-12 month consent duration (max 24 months)
  • Provide clear category descriptions
  • Never pre-tick optional categories
  • Only "strictly necessary" enabled by default

Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • React 18+
  • Next.js 13+

Latest: v2.1.0 - Google Consent Mode V2

  • ✅ Full Google Consent Mode V2 support
  • ✅ Automatic consent default and update
  • ✅ All V2 parameters: ad_user_data, ad_personalization
  • ✅ URL passthrough and ads data redaction
  • ✅ Zero breaking changes

License

MIT © Meui Creative