@tengerly/cookie-consent
Version:
A lightweight, customizable cookie consent solution for Next.js and modern web frameworks with comprehensive multi-language support
489 lines (406 loc) • 13 kB
Markdown
# @tengerly/cookie-consent
A lightweight, customizable cookie consent solution that works perfectly with Next.js and modern web frameworks. Extracted from a production portfolio application with proven GDPR compliance.
[](https://badge.fury.io/js/@tengerly%2Fcookie-consent)
[](https://www.npmjs.com/package/@tengerly/cookie-consent)
[](https://github.com/tengerly/cookie-consent-library/blob/main/LICENSE)
## Features
- 🎨 **Beautiful UI** - Modern, responsive design with smooth animations
- 🌍 **Multi-language** - Built-in support for 7 languages with auto-detection
- ⚡ **Lightweight** - No external dependencies, vanilla JavaScript
- 🔧 **Customizable** - Extensive configuration options and theming
- ⚛️ **React Hook** - Easy integration with Next.js applications
- 📱 **Mobile-first** - Responsive design that works on all devices
- 🍪 **GDPR Compliant** - Granular cookie controls and preferences
- 🎯 **TypeScript** - Full TypeScript support with type definitions
## Multi-Language Support
The library includes comprehensive built-in translations for **7 languages** with automatic browser language detection:
### 🌍 **Supported Languages:**
- **🇺🇸 English (en)** - Default
- **🇫🇷 French (fr)** - Français
- **🇩🇪 German (de)** - Deutsch
- **🇪🇸 Spanish (es)** - Español
- **🇮🇹 Italian (it)** - Italiano
- **🇳🇱 Dutch (nl)** - Nederlands
- **🇵🇹 Portuguese (pt)** - Português
### **Automatic Language Detection**
The library automatically detects the user's browser language:
```javascript
// Automatic detection - no configuration needed!
const cookieConsent = new CookieConsent();
// Will automatically use French for French browsers, German for German browsers, etc.
```
### **Manual Language Selection**
```javascript
// Set specific language
const cookieConsent = new CookieConsent({
language: 'fr' // Force French
});
// React Hook with language
const { consent } = useCookieConsent({
language: 'de' // Force German
});
```
### **Custom Translations**
Add your own language or override existing translations:
```javascript
const cookieConsent = new CookieConsent({
language: 'ja',
translations: {
ja: {
title: 'クッキーの設定',
message: 'このウェブサイトでは、最高のエクスペリエンスを提供するためにクッキーを使用しています。',
acceptAll: 'すべて受け入れる',
acceptSome: 'カスタマイズ',
reject: '必須のみ',
continue: '同意なしで続行',
save: '設定を保存',
close: '閉じる',
functionalTitle: '機能的クッキー',
functionalDesc: 'サイトの適切な機能に必要(言語、テーマ)。常に有効。',
analyticsTitle: '分析クッキー',
analyticsDesc: '訪問者がウェブサイトとどのように相互作用するかを理解するのに役立ちます。'
}
}
});
```
### **Available Translation Methods**
```javascript
// Get available languages
const languages = cookieConsent.getAvailableLanguages();
console.log(languages); // ['en', 'fr', 'de', 'es', 'it', 'nl', 'pt']
// Detect browser language
const detectedLang = cookieConsent.detectLanguage();
console.log(detectedLang); // 'fr' for French browsers
// Change language dynamically
cookieConsent.setLanguage('es');
// Add custom translation
cookieConsent.addCustomTranslation('sv', {
title: 'Cookie-inställningar',
message: 'Denna webbplats använder cookies...',
// ... other translations
});
```
### **Import Translations Separately**
```javascript
// Import translation utilities
import {
translations,
detectLanguage,
getTranslations,
getAvailableLanguages
} from '@tengerly/cookie-consent/translations';
const userLang = detectLanguage();
const texts = getTranslations(userLang);
console.log(texts.title); // Localized title
```
## Installation
### NPM Installation (Recommended)
```bash
npm install @tengerly/cookie-consent
```
```bash
yarn add @tengerly/cookie-consent
```
```bash
pnpm add @tengerly/cookie-consent
```
### CDN Installation
```html
<script src="https://unpkg.com/@tengerly/cookie-consent@latest/dist/cookie-consent-library.js"></script>
```
## Usage
### Basic Usage with React Hook (Next.js)
```typescript
// pages/_app.tsx or app/layout.tsx
import { useCookieConsent } from '@tengerly/cookie-consent/react';
export default function App({ Component, pageProps }) {
const { consent, hasConsent, showPreferences } = useCookieConsent({
language: 'en',
delay: 3000,
onAcceptAll: () => {
console.log('All cookies accepted');
// Enable analytics
gtag('consent', 'update', {
'analytics_storage': 'granted'
});
},
onAcceptEssential: () => {
console.log('Essential cookies only');
},
onAcceptCustom: (level, preferences) => {
console.log('Custom preferences:', level, preferences);
if (preferences.analytics) {
// Enable analytics
gtag('consent', 'update', {
'analytics_storage': 'granted'
});
}
}
});
return (
<>
<Component {...pageProps} />
{/* Optional: Cookie preferences button */}
<button
onClick={showPreferences}
style={{ position: 'fixed', bottom: '20px', left: '20px' }}
>
Cookie Settings
</button>
</>
);
}
```
### Vanilla JavaScript Usage
```html
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/@tengerly/cookie-consent@latest/dist/cookie-consent-library.js"></script>
</head>
<body>
<script>
// Initialize cookie consent
const cookieConsent = new CookieConsent({
language: 'en',
delay: 3000,
onAcceptAll: () => {
console.log('All cookies accepted');
enableAnalytics();
},
onAcceptEssential: () => {
console.log('Essential cookies only');
}
});
// Show preferences manually
function showCookiePreferences() {
cookieConsent.showPreferences();
}
function enableAnalytics() {
// Your analytics code here
if (typeof gtag !== 'undefined') {
gtag('consent', 'update', {
'analytics_storage': 'granted'
});
}
}
</script>
</body>
</html>
```
### Next.js App Router Usage
```typescript
// app/layout.tsx
'use client';
import { useCookieConsent } from '@tengerly/cookie-consent/react';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const { consent, hasConsent } = useCookieConsent({
language: 'en',
translations: {
en: {
title: 'We value your privacy',
message: 'This website uses cookies to provide you with the best possible experience.',
acceptAll: 'Accept All',
acceptSome: 'Customize',
reject: 'Reject All',
continue: 'Continue',
save: 'Save Settings',
close: 'Close',
functionalTitle: 'Functional Cookies',
functionalDesc: 'Essential cookies for website functionality.',
analyticsTitle: 'Analytics Cookies',
analyticsDesc: 'Help us improve our website.'
}
}
});
return (
<html>
<body>
{children}
{/* Conditionally load analytics based on consent */}
{hasConsent('all') && (
<script
dangerouslySetInnerHTML={{
__html: `
gtag('config', 'GA_MEASUREMENT_ID');
`
}}
/>
)}
</body>
</html>
);
}
```
## Configuration Options
```typescript
interface CookieConsentOptions {
// Basic settings
cookieName?: string; // Default: 'portfolio_cookie_consent'
cookieExpiryDays?: number; // Default: 365
delay?: number; // Default: 3000ms
autoShow?: boolean; // Default: true
language?: string; // Default: 'en'
// Styling
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'bottom-center' | 'top-center';
theme?: string; // Default: 'default'
// Translations
translations?: {
[language: string]: {
title: string;
message: string;
acceptAll: string;
acceptSome: string;
reject: string;
continue: string;
save: string;
close: string;
functionalTitle: string;
functionalDesc: string;
analyticsTitle: string;
analyticsDesc: string;
};
};
// Callbacks
onAcceptAll?: () => void;
onAcceptEssential?: () => void;
onAcceptCustom?: (level: string, preferences: { analytics: boolean }) => void;
onReject?: () => void;
}
```
## API Reference
### CookieConsent Class
```typescript
class CookieConsent {
constructor(options?: CookieConsentOptions);
// Widget control
show(): void; // Show the consent widget
hide(): void; // Hide the consent widget
showPreferences(): void; // Show preferences modal
hidePreferences(): void; // Hide preferences modal
// Consent management
acceptAll(): void; // Accept all cookies
acceptEssential(): void; // Accept essential cookies only
saveCustomPreferences(): void; // Save custom preferences
// State management
getConsent(): string | null; // Get current consent level
hasConsent(type?: 'all' | 'essential'): boolean;
setConsent(level: 'all' | 'essential'): void;
resetConsent(): void; // Reset and show widget again
// Language support
setLanguage(language: string): void;
detectLanguage(): string;
getTranslations(): any;
getAvailableLanguages(): string[];
addCustomTranslation(languageCode: string, translations: any): void;
// Utility
remove(): void; // Clean up and remove
enableAnalytics(): void; // Override for custom analytics
// Static methods
static create(options?: CookieConsentOptions): CookieConsent;
}
```
### React Hook
```typescript
const {
consent, // Current consent level: 'all' | 'essential' | null
hasConsent, // Function to check consent
showWidget, // Show the consent widget
showPreferences, // Show preferences modal
resetConsent, // Reset consent and show widget
isLoaded // Whether library is loaded and ready
} = useCookieConsent(options);
```
## Styling and Theming
The library includes beautiful default styles, but you can customize them:
```css
/* Override default styles */
.cookie-consent {
--primary-color: #6366f1;
--background-color: white;
--text-color: #1a1a1a;
--border-radius: 12px;
}
/* Custom positioning */
.cookie-consent {
bottom: 20px;
left: 20px; /* Move to bottom-left */
}
/* Dark theme example */
.cookie-consent.dark-theme {
background: #1f2937;
color: white;
}
```
## Google Analytics Integration
```typescript
const { hasConsent } = useCookieConsent({
onAcceptAll: () => {
// Enable Google Analytics
gtag('consent', 'update', {
'analytics_storage': 'granted',
'ad_storage': 'granted'
});
},
onAcceptEssential: () => {
// Disable analytics
gtag('consent', 'update', {
'analytics_storage': 'denied',
'ad_storage': 'denied'
});
}
});
// Check consent before loading analytics
useEffect(() => {
if (hasConsent('all')) {
// Load Google Analytics
const script = document.createElement('script');
script.src = `https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID`;
document.head.appendChild(script);
}
}, [hasConsent]);
```
## Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- iOS Safari 12+
- Android Chrome 60+
## Contributing
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
MIT License - see LICENSE file for details.
## Changelog
### v1.1.2
- Fixed README to focus on cookie consent library instead of portfolio website
- Improved documentation structure and organization
### v1.1.1
- Updated to 7 supported languages
- Improved button styling and organization
### v1.1.0
- Added comprehensive multi-language support
- Added 8 languages with auto-detection
- Added separate translations module
- Enhanced TypeScript definitions
### v1.0.1
- Fixed button layout and styling issues
- Improved mobile responsiveness
- Better visual hierarchy
### v1.0.0
- Initial release
- Multi-language support (EN, FR, DE)
- React hook for Next.js
- TypeScript definitions
- Responsive design
- GDPR compliance
---
**Built with ❤️ by Tengerly for the developer community**