# @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.

[![npm version](https://badge.fury.io/js/@tengerly%2Fcookie-consent.svg)](https://badge.fury.io/js/@tengerly%2Fcookie-consent)
[![downloads](https://img.shields.io/npm/dm/@tengerly/cookie-consent.svg)](https://www.npmjs.com/package/@tengerly/cookie-consent)
[![license](https://img.shields.io/npm/l/@tengerly/cookie-consent.svg)](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** 