@tengerly/cookie-consent
Version:
A lightweight, customizable cookie consent solution for Next.js and modern web frameworks with comprehensive multi-language support
177 lines (160 loc) • 5.12 kB
JavaScript
// Cookie Consent React Hook for Next.js
// This file should be placed in your Next.js project and imported only in React components
'use client'; // For Next.js App Router
import { useEffect, useRef, useState } from 'react';
export interface CookieConsentOptions {
cookieName?: string;
cookieExpiryDays?: number;
delay?: number;
autoShow?: boolean;
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'bottom-center' | 'top-center';
theme?: string;
language?: 'en' | 'fr' | 'de' | string;
translations?: {
[key: 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;
};
};
onAcceptAll?: () => void;
onAcceptEssential?: () => void;
onAcceptCustom?: (level: string, preferences: { analytics: boolean }) => void;
onReject?: () => void;
}
export interface CookieConsentInstance {
show(): void;
hide(): void;
showPreferences(): void;
hidePreferences(): void;
acceptAll(): void;
acceptEssential(): void;
saveCustomPreferences(): void;
setConsent(level: 'all' | 'essential'): void;
getConsent(): string | null;
hasConsent(type?: 'all' | 'essential'): boolean;
resetConsent(): void;
remove(): void;
setLanguage(language: string): void;
enableAnalytics(): void;
}
export interface UseCookieConsentReturn {
consent: string | null;
hasConsent: (type?: 'all' | 'essential') => boolean;
showWidget: () => void;
showPreferences: () => void;
resetConsent: () => void;
isLoaded: boolean;
}
declare global {
interface Window {
CookieConsent: any;
}
}
export const useCookieConsent = (options?: CookieConsentOptions): UseCookieConsentReturn => {
const consentRef = useRef<CookieConsentInstance | null>(null);
const [consent, setConsent] = useState<string | null>(null);
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
// Only run on client side
if (typeof window === 'undefined') return;
const initializeCookieConsent = async () => {
try {
// Check if library is already loaded
if (window.CookieConsent) {
const instance = new window.CookieConsent({
autoShow: true,
delay: 3000,
...options,
onAcceptAll: () => {
setConsent('all');
options?.onAcceptAll?.();
},
onAcceptEssential: () => {
setConsent('essential');
options?.onAcceptEssential?.();
},
onAcceptCustom: (level: string, preferences: { analytics: boolean }) => {
setConsent(level);
options?.onAcceptCustom?.(level, preferences);
},
});
consentRef.current = instance;
setConsent(instance.getConsent());
setIsLoaded(true);
} else {
// Load script dynamically if not available
const script = document.createElement('script');
script.src = '/cookie-consent-library.js';
script.onload = () => {
if (window.CookieConsent) {
const instance = new window.CookieConsent({
autoShow: true,
delay: 3000,
...options,
onAcceptAll: () => {
setConsent('all');
options?.onAcceptAll?.();
},
onAcceptEssential: () => {
setConsent('essential');
options?.onAcceptEssential?.();
},
onAcceptCustom: (level: string, preferences: { analytics: boolean }) => {
setConsent(level);
options?.onAcceptCustom?.(level, preferences);
},
});
consentRef.current = instance;
setConsent(instance.getConsent());
setIsLoaded(true);
}
};
script.onerror = () => {
console.error('Failed to load cookie consent library from /cookie-consent-library.js');
};
document.head.appendChild(script);
}
} catch (error) {
console.error('Failed to initialize cookie consent:', error);
}
};
initializeCookieConsent();
// Cleanup on unmount
return () => {
if (consentRef.current) {
consentRef.current.remove();
}
};
}, []);
const hasConsent = (type: 'all' | 'essential' = 'all'): boolean => {
return consentRef.current?.hasConsent(type) || false;
};
const showWidget = (): void => {
consentRef.current?.show();
};
const showPreferences = (): void => {
consentRef.current?.showPreferences();
};
const resetConsent = (): void => {
consentRef.current?.resetConsent();
setConsent(null);
};
return {
consent,
hasConsent,
showWidget,
showPreferences,
resetConsent,
isLoaded,
};
};