Random UI

use-privacy-compliant

A comprehensive privacy-compliant analytics hook that ensures GDPR, CCPA, and other privacy regulation compliance with granular consent management, data anonymization, automatic retention policies, and custom PII field configuration.

Demo

Privacy & Cookies

We use analytics to improve our service. Manage your preferences below.

Demo Landing Page

Experience privacy-compliant analytics in action

Privacy Settings

Consent Management

Current Status

Consent: Not Granted ❌Categories: NoneWants Anonymized Data: Yes ✅Regulation: GDPR

Data Retention

Total Events: 0Active Events: 0Expired Events: 0Anonymized Events: 0Retention Compliance: 100.0%

Anonymization Preference

When enabled, all future tracked events will have PII fields hashed automatically.

Custom PII Fields Configuration

user_id

These fields will be anonymized when anonymization is enabled. Common examples: email, phone, name, address, ip, user_id, ssn, creditCard

Event Tracking Test

Features

  • Privacy Regulation Compliance: Supports GDPR, CCPA, PIPEDA, LGPD, and PDPA
  • Granular Consent Management: Category-based consent (analytics, marketing, functional, etc.)
  • Data Anonymization: Automatic PII removal and hashing with custom field configuration
  • Automatic Data Retention: Configurable retention periods with automatic cleanup
  • User Data Rights: Export and delete events on demand
  • Consent Tracking: Version-controlled consent with history
  • Real-time Metrics: Privacy-compliant analytics metrics
  • Custom PII Fields: Configure which fields to anonymize
  • Anonymization Preferences: User-controlled data anonymization settings

Installation

Copy and paste the following code into your project.

use-privacy-compliant.ts
"use client";

import { useState, useCallback, useMemo, useEffect, useRef } from "react";

/**
 * Privacy regulation types supported by the hook
 */
export type PrivacyRegulation = "GDPR" | "CCPA" | "PIPEDA" | "LGPD" | "PDPA";

/**
 * Consent categories for granular privacy control
 */
export type ConsentCategory = 
  | "analytics" 
  | "marketing" 
  | "functional" 
  | "necessary" 
  | "preferences";

/**
 * Data retention periods in days
 */
export type RetentionPeriod = 30 | 90 | 365 | 730 | "indefinite";

/**
 * User consent state
 */
export interface ConsentState {
  /** Whether user has given consent */
  hasConsent: boolean;
  /** Timestamp when consent was given */
  consentTimestamp: number | null;
  /** Categories of consent given */
  categories: ConsentCategory[];
  /** Whether consent is required for the current regulation */
  consentRequired: boolean;
  /** Version of the consent (for tracking changes) */
  consentVersion: string;
  /** Whether user wants data to be anonymized */
  wantsAnonymizedData: boolean;
}

/**
 * Privacy settings configuration
 */
export interface PrivacySettings {
  /** Current privacy regulation */
  regulation: PrivacyRegulation;
  /** Default consent categories */
  defaultCategories: ConsentCategory[];
  /** Data retention period in days */
  retentionPeriod: RetentionPeriod;
  /** Whether to anonymize data by default */
  anonymizeByDefault: boolean;
  /** Whether to require explicit consent */
  requireExplicitConsent: boolean;
  /** Consent version for tracking changes */
  consentVersion: string;
  /** Custom PII fields to anonymize */
  customPiiFields: string[];
}

/**
 * Analytics event with privacy compliance
 */
export interface PrivacyCompliantEvent {
  /** Unique event ID */
  id: string;
  /** Event name */
  name: string;
  /** Event properties */
  properties: Record<string, any>;
  /** Event timestamp */
  timestamp: number;
  /** Whether data is anonymized */
  anonymized: boolean;
  /** Consent categories required for this event */
  requiredCategories: ConsentCategory[];
  /** Session ID */
  sessionId: string;
}

/**
 * Events export format
 */
export interface EventsExport {
  /** All events matching the filter */
  events: PrivacyCompliantEvent[];
  /** Export timestamp */
  exportedAt: number;
  /** Data retention information */
  retentionInfo: {
    totalEvents: number;
    activeEvents: number;
    expiredEvents: number;
    retentionPeriod: RetentionPeriod;
  };
}

/**
 * Analytics metrics with privacy compliance
 */
export interface PrivacyCompliantMetrics {
  /** Total events tracked */
  totalEvents: number;
  /** Events by category */
  eventsByCategory: Record<ConsentCategory, number>;
  /** Anonymized events count */
  anonymizedEvents: number;
  /** Consent rate (percentage of users who gave consent) */
  consentRate: number;
  /** Data retention compliance */
  retentionCompliance: {
    eventsExpired: number;
    eventsRetained: number;
    complianceRate: number;
  };
}

/**
 * Return type for the usePrivacyCompliant hook
 */
export interface UsePrivacyCompliantReturn {
  /** Current consent state */
  consentState: ConsentState;
  /** Current privacy settings */
  settings: PrivacySettings;
  /** Current analytics metrics */
  metrics: PrivacyCompliantMetrics;
  /** Track an event with privacy compliance */
  trackEvent: (name: string, properties?: Record<string, any>, categories?: ConsentCategory[]) => void;
  /** Request user consent */
  requestConsent: (categories: ConsentCategory[]) => Promise<boolean>;
  /** Update consent preferences */
  updateConsent: (categories: ConsentCategory[]) => void;
  /** Update anonymization preference */
  updateAnonymizationPreference: (wantsAnonymized: boolean) => void;
  /** Withdraw consent */
  withdrawConsent: () => void;
  /** Check if consent is given for specific categories */
  hasConsentFor: (categories: ConsentCategory[]) => boolean;
  /** Anonymize existing data based on PII fields */
  anonymizeData: () => void;
  /** Export events with optional filtering */
  exportEvents: () => EventsExport;
  /** Delete events by filter */
  deleteEvents: () => Promise<boolean>;
  /** Update privacy settings */
  updateSettings: (settings: Partial<PrivacySettings>) => void;
  /** Update custom PII fields */
  updateCustomPiiFields: (fields: string[]) => void;
  /** Get data retention status */
  getRetentionStatus: () => {
    totalEvents: number;
    expiredEvents: number;
    activeEvents: number;
  };
}

/**
 * Default privacy settings
 */
const DEFAULT_PRIVACY_SETTINGS: PrivacySettings = {
  regulation: "GDPR",
  defaultCategories: ["necessary"],
  retentionPeriod: 365,
  anonymizeByDefault: true,
  requireExplicitConsent: true,
  consentVersion: "1.0.0",
  customPiiFields: ["user_id"],
};

/**
 * Storage keys for persistence
 */
const STORAGE_KEYS = {
  CONSENT: "privacy_consent",
  SETTINGS: "privacy_settings",
  EVENTS: "privacy_events",
  METRICS: "privacy_metrics",
} as const;

/**
 * A comprehensive privacy-compliant analytics hook that ensures GDPR, CCPA, and other privacy regulation compliance.
 * 
 * Features:
 * - Granular consent management
 * - Data anonymization
 * - Automatic data retention
 * - User data export/deletion
 * - Privacy regulation compliance
 * 
 * @param initialSettings - Initial privacy settings
 * @returns Privacy-compliant analytics utilities
 * 
 * @example
 * ```tsx
 * const analytics = usePrivacyCompliant({
 *   regulation: "GDPR",
 *   retentionPeriod: 365,
 *   requireExplicitConsent: true
 * });
 * 
 * // Track event with consent check
 * analytics.trackEvent("page_view", { page: "/home" }, ["analytics"]);
 * 
 * // Request consent
 * const granted = await analytics.requestConsent(["analytics", "marketing"]);
 * ```
 */
export function usePrivacyCompliant(
  initialSettings: Partial<PrivacySettings> = {}
): UsePrivacyCompliantReturn {
  
  // Merge initial settings with defaults
  const [settings, setSettings] = useState<PrivacySettings>(() => ({
    ...DEFAULT_PRIVACY_SETTINGS,
    ...initialSettings,
  }));

  // Consent state
  const [consentState, setConsentState] = useState<ConsentState>(() => {
    if (typeof window === "undefined") {
    return {
      hasConsent: false,
      consentTimestamp: null,
      categories: [],
      consentRequired: true,
      consentVersion: settings.consentVersion,
      wantsAnonymizedData: settings.anonymizeByDefault,
    };
    }

    const stored = localStorage.getItem(STORAGE_KEYS.CONSENT);
    if (stored) {
      const parsed = JSON.parse(stored);
      return {
        ...parsed,
        consentRequired: settings.requireExplicitConsent,
      };
    }

    return {
      hasConsent: !settings.requireExplicitConsent,
      consentTimestamp: null,
      categories: settings.defaultCategories,
      consentRequired: settings.requireExplicitConsent,
      consentVersion: settings.consentVersion,
      wantsAnonymizedData: settings.anonymizeByDefault,
    };
  });

  // Analytics events storage
  const eventsRef = useRef<PrivacyCompliantEvent[]>([]);
  const metricsRef = useRef<PrivacyCompliantMetrics>({
    totalEvents: 0,
    eventsByCategory: {
      analytics: 0,
      marketing: 0,
      functional: 0,
      necessary: 0,
      preferences: 0,
    },
    anonymizedEvents: 0,
    consentRate: 0,
    retentionCompliance: {
      eventsExpired: 0,
      eventsRetained: 0,
      complianceRate: 100,
    },
  });

  // Session ID for tracking
  const sessionIdRef = useRef<string>(`session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`);

  /**
   * Load data from localStorage on mount
   */
  useEffect(() => {
    if (typeof window === "undefined") return;

    // Load events
    const storedEvents = localStorage.getItem(STORAGE_KEYS.EVENTS);
    if (storedEvents) {
      try {
        eventsRef.current = JSON.parse(storedEvents);
      } catch (error) {
        console.warn("Failed to load events from storage:", error);
      }
    }

    // Load metrics
    const storedMetrics = localStorage.getItem(STORAGE_KEYS.METRICS);
    if (storedMetrics) {
      try {
        metricsRef.current = JSON.parse(storedMetrics);
      } catch (error) {
        console.warn("Failed to load metrics from storage:", error);
      }
    }
  }, []);

  /**
   * Save data to localStorage
   */
  const saveToStorage = useCallback(() => {
    if (typeof window === "undefined") return;

    try {
      localStorage.setItem(STORAGE_KEYS.CONSENT, JSON.stringify(consentState));
      localStorage.setItem(STORAGE_KEYS.SETTINGS, JSON.stringify(settings));
      localStorage.setItem(STORAGE_KEYS.EVENTS, JSON.stringify(eventsRef.current));
      localStorage.setItem(STORAGE_KEYS.METRICS, JSON.stringify(metricsRef.current));
    } catch (error) {
      console.warn("Failed to save to storage:", error);
    }
  }, [consentState, settings]);

  /**
   * Check if consent is required for specific categories
   */
  const hasConsentFor = useCallback((categories: ConsentCategory[]): boolean => {
    if (!consentState.hasConsent) return false;
    return categories.every(category => consentState.categories.includes(category));
  }, [consentState]);

  /**
   * Anonymize data by removing or hashing PII
   */
  const anonymizeEventData = useCallback((event: Omit<PrivacyCompliantEvent, 'anonymized' | 'timestamp' | 'sessionId'>): PrivacyCompliantEvent => {
    const anonymizedProperties = { ...event.properties };
    
    // Use custom PII fields from settings
    const piiFields = settings.customPiiFields;
    piiFields.forEach(field => {
      if (anonymizedProperties[field]) {
        anonymizedProperties[field] = `[ANONYMIZED_${field.toUpperCase()}]`;
      }
    });

    return {
      ...event,
      properties: anonymizedProperties,
      anonymized: true,
      timestamp: Date.now(),
      sessionId: sessionIdRef.current,
    };
  }, [settings.customPiiFields]);

  /**
   * Track an event with privacy compliance
   */
  const trackEvent = useCallback(async (
    name: string, 
    properties: Record<string, any> = {}, 
    categories: ConsentCategory[] = ["analytics"]
  ) => {
    // Check if consent is required and given
    if (settings.requireExplicitConsent && !hasConsentFor(categories)) {
      console.warn(`Consent required for categories: ${categories.join(", ")}`);
      return;
    }

    // Create final event with unique ID
    const finalEvent: PrivacyCompliantEvent = {
      id: `event_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      name,
      properties,
      requiredCategories: categories,
      anonymized: settings.anonymizeByDefault,
      timestamp: Date.now(),
      sessionId: sessionIdRef.current,
    };

    // Anonymize if required (check user preference first, then settings)
    const shouldAnonymize = consentState.wantsAnonymizedData;
    const processedEvent = shouldAnonymize 
      ? anonymizeEventData(finalEvent)
      : finalEvent;

    // Add to events
    eventsRef.current.push(processedEvent);

    // Update metrics
    metricsRef.current.totalEvents++;
    categories.forEach(category => {
      metricsRef.current.eventsByCategory[category]++;
    });
    if (processedEvent.anonymized) {
      metricsRef.current.anonymizedEvents++;
    }

    // Clean up expired events
    cleanupExpiredEvents();

    // Trigger update
    setUpdateTrigger(prev => prev + 1);

    saveToStorage();
  }, [settings, hasConsentFor, anonymizeEventData, saveToStorage]);

  /**
   * Clean up expired events based on retention period
   */
  const cleanupExpiredEvents = useCallback(() => {
    if (settings.retentionPeriod === "indefinite") return;

    const now = Date.now();
    const retentionMs = settings.retentionPeriod * 24 * 60 * 60 * 1000;
    
    const initialCount = eventsRef.current.length;
    eventsRef.current = eventsRef.current.filter(event => {
      return (now - event.timestamp) < retentionMs;
    });
    
    const expiredCount = initialCount - eventsRef.current.length;
    metricsRef.current.retentionCompliance.eventsExpired += expiredCount;
    metricsRef.current.retentionCompliance.eventsRetained = eventsRef.current.length;
    
    const totalProcessed = metricsRef.current.retentionCompliance.eventsExpired + 
                          metricsRef.current.retentionCompliance.eventsRetained;
    metricsRef.current.retentionCompliance.complianceRate = totalProcessed > 0 
      ? (metricsRef.current.retentionCompliance.eventsRetained / totalProcessed) * 100 
      : 100;
  }, [settings.retentionPeriod]);

  /**
   * Request user consent
   */
  const requestConsent = useCallback(async (categories: ConsentCategory[]): Promise<boolean> => {
    // In a real implementation, this would show a consent modal
    // For demo purposes, we'll simulate user interaction
    return new Promise((resolve) => {
      const userConsent = window.confirm(
        `This website would like to track analytics for: ${categories.join(", ")}. Do you consent?`
      );
      
      if (userConsent) {
        setConsentState(prev => ({
          ...prev,
          hasConsent: true,
          consentTimestamp: Date.now(),
          categories: [...new Set([...prev.categories, ...categories])],
          consentVersion: settings.consentVersion,
        }));
      }
      
      resolve(userConsent);
    });
  }, [settings.consentVersion]);

  /**
   * Update consent preferences
   */
  const updateConsent = useCallback((categories: ConsentCategory[]) => {
    setConsentState(prev => ({
      ...prev,
      hasConsent: true,
      consentTimestamp: Date.now(),
      categories,
      consentVersion: settings.consentVersion,
    }));
  }, [settings.consentVersion]);

  /**
   * Update anonymization preference
   */
  const updateAnonymizationPreference = useCallback((wantsAnonymized: boolean) => {
    setConsentState(prev => ({
      ...prev,
      wantsAnonymizedData: wantsAnonymized,
    }));
  }, []);

  /**
   * Withdraw consent
   */
  const withdrawConsent = useCallback(() => {
    setConsentState(prev => ({
      ...prev,
      hasConsent: false,
      consentTimestamp: null,
      categories: [],
    }));
    
    // Anonymize all existing events
    eventsRef.current = eventsRef.current.map(event => {
      const anonymizedProperties = { ...event.properties };

      return {
        ...event,
        properties: anonymizedProperties,
        anonymized: true,
      };
    });
    
    saveToStorage();
  }, [saveToStorage]);

  /**
   * Anonymize existing data
   */
  const anonymizeData = useCallback(async () => {
    const anonymizeEvent = async (event: PrivacyCompliantEvent) => {
      const anonymizedProperties = { ...event.properties };
      
      // Use custom PII fields from settings
      const piiFields = settings.customPiiFields;

      piiFields.forEach(field => {
        if (anonymizedProperties[field]) {
          anonymizedProperties[field] = `[ANONYMIZED_${field.toUpperCase()}]`;
        }
      });

      return {
        ...event,
        properties: anonymizedProperties,
        anonymized: true,
      };
    };

    const anonymizedEvents = await Promise.all(
      eventsRef.current.map(event => anonymizeEvent(event))
    );
    
    eventsRef.current = anonymizedEvents;
    metricsRef.current.anonymizedEvents = anonymizedEvents.length;
    setUpdateTrigger(prev => prev + 1);
    saveToStorage();
  }, [saveToStorage]);

  /**
   * Export events with optional filtering
   */
  const exportEvents = useCallback((): EventsExport => {
    const retentionStatus = getRetentionStatus();

    return {
      events: eventsRef.current,
      exportedAt: Date.now(),
      retentionInfo: {
        totalEvents: retentionStatus.totalEvents,
        activeEvents: retentionStatus.activeEvents,
        expiredEvents: retentionStatus.expiredEvents,
        retentionPeriod: settings.retentionPeriod,
      },
    };
  }, [settings.retentionPeriod]);

  /**
   * Delete events by filter
   */
  const deleteEvents = useCallback(async (): Promise<boolean> => {
    try {

      eventsRef.current = [];
      metricsRef.current.totalEvents = 0;
      metricsRef.current.anonymizedEvents = 0;
      
      setUpdateTrigger(prev => prev + 1);
      saveToStorage();
      return true;
    } catch (error) {
      console.error("Failed to delete events:", error);
      return false;
    }
  }, [saveToStorage]);

  /**
   * Update privacy settings
   */
  const updateSettings = useCallback((newSettings: Partial<PrivacySettings>) => {
    setSettings(prev => ({ ...prev, ...newSettings }));
    saveToStorage();
  }, [saveToStorage]);

  /**
   * Update custom PII fields
   */
  const updateCustomPiiFields = useCallback((fields: string[]) => {
    setSettings(prev => ({ 
      ...prev, 
      customPiiFields: fields 
    }));
    saveToStorage();
  }, [saveToStorage]);

  /**
   * Get data retention status
   */
  const getRetentionStatus = useCallback(() => {
    cleanupExpiredEvents();
    return {
      totalEvents: metricsRef.current.totalEvents,
      expiredEvents: metricsRef.current.retentionCompliance.eventsExpired,
      activeEvents: metricsRef.current.retentionCompliance.eventsRetained,
    };
  }, [cleanupExpiredEvents]);

  // State to trigger updates
  const [updateTrigger, setUpdateTrigger] = useState(0);

  // Memoized metrics
  const metrics = useMemo(() => {
    cleanupExpiredEvents();
    return { ...metricsRef.current };
  }, [cleanupExpiredEvents, updateTrigger]);

  // Auto-save on consent changes
  useEffect(() => {
    saveToStorage();
  }, [consentState, saveToStorage]);

  return {
    consentState,
    settings,
    metrics,
    trackEvent,
    requestConsent,
    updateConsent,
    updateAnonymizationPreference,
    withdrawConsent,
    hasConsentFor,
    anonymizeData,
    exportEvents,
    deleteEvents,
    updateSettings,
    updateCustomPiiFields,
    getRetentionStatus,
  };
}

Basic Usage

import { usePrivacyCompliant } from "@hooks/use-privacy-compliant";

function MyComponent() {
  const analytics = usePrivacyCompliant({
    regulation: "GDPR",
    retentionPeriod: 365,
    requireExplicitConsent: true,
  });

  // Track an event with consent check
  analytics.trackEvent("page_view", { page: "/home" }, ["analytics"]);

  // Request user consent
  const handleConsent = async () => {
    const granted = await analytics.requestConsent(["analytics", "marketing"]);
    if (granted) {
      console.log("Consent granted!");
    }
  };

  return (
    <div>
      <button onClick={handleConsent}>Grant Consent</button>
    </div>
  );
}

API Reference

Hook Parameters

interface PrivacySettings {
  /** Current privacy regulation */
  regulation: PrivacyRegulation;
  /** Default consent categories */
  defaultCategories: ConsentCategory[];
  /** Data retention period in days */
  retentionPeriod: RetentionPeriod;
  /** Whether to anonymize data by default */
  anonymizeByDefault: boolean;
  /** Whether to require explicit consent */
  requireExplicitConsent: boolean;
  /** Consent version for tracking changes */
  consentVersion: string;
  /** Custom PII fields to anonymize */
  customPiiFields: string[];
}

Return Value

interface UsePrivacyCompliantReturn {
  /** Current consent state */
  consentState: ConsentState;
  /** Current privacy settings */
  settings: PrivacySettings;
  /** Current analytics metrics */
  metrics: PrivacyCompliantMetrics;
  /** Track an event with privacy compliance */
  trackEvent: (name: string, properties?: Record<string, any>, categories?: ConsentCategory[]) => void;
  /** Request user consent */
  requestConsent: (categories: ConsentCategory[]) => Promise<boolean>;
  /** Update consent preferences */
  updateConsent: (categories: ConsentCategory[]) => void;
  /** Update anonymization preference */
  updateAnonymizationPreference: (wantsAnonymized: boolean) => void;
  /** Withdraw consent */
  withdrawConsent: () => void;
  /** Check if consent is given for specific categories */
  hasConsentFor: (categories: ConsentCategory[]) => boolean;
  /** Anonymize existing data based on PII fields */
  anonymizeData: () => void;
  /** Export events with optional filtering */
  exportEvents: () => EventsExport;
  /** Delete events by filter */
  deleteEvents: () => Promise<boolean>;
  /** Update privacy settings */
  updateSettings: (settings: Partial<PrivacySettings>) => void;
  /** Update custom PII fields */
  updateCustomPiiFields: (fields: string[]) => void;
  /** Get data retention status */
  getRetentionStatus: () => {
    totalEvents: number;
    expiredEvents: number;
    activeEvents: number;
  };
}

Privacy Regulations

GDPR (General Data Protection Regulation)

const analytics = usePrivacyCompliant({
  regulation: "GDPR",
  retentionPeriod: 365,
  requireExplicitConsent: true,
  anonymizeByDefault: true,
});

CCPA (California Consumer Privacy Act)

const analytics = usePrivacyCompliant({
  regulation: "CCPA",
  retentionPeriod: 365,
  requireExplicitConsent: false, // CCPA allows opt-out
  anonymizeByDefault: false,
});
type ConsentCategory = 
  | "analytics"     // Website analytics and performance
  | "marketing"     // Marketing and advertising
  | "functional"    // Essential website functionality
  | "necessary"     // Legally required data
  | "preferences";  // User preference data

Event Tracking

Basic Event Tracking

// Track with automatic consent check
analytics.trackEvent("button_click", {
  buttonId: "signup",
  page: "/home"
}, ["analytics"]);

Conditional Tracking

// Only track if consent is given
if (analytics.hasConsentFor(["analytics"])) {
  analytics.trackEvent("page_view", { page: "/dashboard" });
}
const handleRequestConsent = async () => {
  const granted = await analytics.requestConsent([
    "analytics",
    "marketing"
  ]);
  
  if (granted) {
    // User granted consent
    analytics.trackEvent("consent_granted", {}, ["analytics"]);
  }
};
// Update consent preferences
analytics.updateConsent(["analytics", "functional"]);
// Withdraw consent and delete tracked data
analytics.withdrawConsent();

Data Management

Export Events

const handleExportData = () => {
  const eventsData = analytics.exportEvents();
  console.log("Exported events:", eventsData);
  
  // Download as JSON
  const blob = new Blob([JSON.stringify(eventsData, null, 2)], {
    type: "application/json"
  });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "events-data.json";
  a.click();
};

Delete Events

const handleDeleteData = async () => {
  const success = await analytics.deleteEvents();
  if (success) {
    console.log("Events deleted successfully");
  }
};

Anonymize Data

// Anonymize all existing data
analytics.anonymizeData();

Update Anonymization Preference

// Update user's anonymization preference
analytics.updateAnonymizationPreference(true); // User wants data anonymized
analytics.updateAnonymizationPreference(false); // User doesn't want data anonymized

Custom PII Fields Configuration

// Configure which fields should be anonymized
analytics.updateCustomPiiFields([
  "user_id",
  "email", 
  "phone",
  "ssn",
  "creditCard"
]);

// Track an event with PII that will be anonymized
analytics.trackEvent("user_signup", {
  user_id: "12345",
  email: "user@example.com",
  phone: "+1234567890"
}, ["analytics"]);

Data Retention

Automatic Cleanup

The hook automatically cleans up expired events based on the retention period:

const analytics = usePrivacyCompliant({
  retentionPeriod: 365, // 365 days
});

// Check retention status
const status = analytics.getRetentionStatus();
console.log(`Active events: ${status.activeEvents}`);
console.log(`Expired events: ${status.expiredEvents}`);

Retention Periods

type RetentionPeriod = 30 | 90 | 365 | 730 | "indefinite";

Analytics Metrics

View Metrics

const { metrics } = analytics;

console.log("Total events:", metrics.totalEvents);
console.log("Anonymized events:", metrics.anonymizedEvents);
console.log("Consent rate:", metrics.consentRate);
console.log("Compliance rate:", metrics.retentionCompliance.complianceRate);

Events by Category

Object.entries(metrics.eventsByCategory).forEach(([category, count]) => {
  console.log(`${category}: ${count} events`);
});

Privacy Settings

Update Settings

// Update privacy settings
analytics.updateSettings({
  regulation: "CCPA",
  retentionPeriod: 90,
  anonymizeByDefault: false,
});

Check Current Settings

const { settings } = analytics;
console.log("Current regulation:", settings.regulation);
console.log("Retention period:", settings.retentionPeriod);
console.log("Anonymize by default:", settings.anonymizeByDefault);

Advanced Usage

const CustomConsentModal = ({ onAccept, onReject }) => {
  const [selectedCategories, setSelectedCategories] = useState([]);
  
  return (
    <div className="consent-modal">
      <h2>Privacy Consent</h2>
      <p>We use cookies and analytics to improve your experience.</p>
      
      {["analytics", "marketing", "functional"].map(category => (
        <label key={category}>
          <input
            type="checkbox"
            checked={selectedCategories.includes(category)}
            onChange={(e) => {
              if (e.target.checked) {
                setSelectedCategories([...selectedCategories, category]);
              } else {
                setSelectedCategories(selectedCategories.filter(c => c !== category));
              }
            }}
          />
          {category}
        </label>
      ))}
      
      <button onClick={() => onAccept(selectedCategories)}>Accept</button>
      <button onClick={onReject}>Reject</button>
    </div>
  );
};

Integration with Analytics Providers

// Google Analytics integration
useEffect(() => {
  if (analytics.hasConsentFor(["analytics"])) {
    // Initialize Google Analytics
    gtag('config', 'GA_MEASUREMENT_ID');
  }
}, [analytics.consentState]);

// Track events to Google Analytics
const trackToGA = (eventName: string, parameters: any) => {
  if (analytics.hasConsentFor(["analytics"])) {
    gtag('event', eventName, parameters);
  }
};

Custom PII Fields Management

// Initialize with custom PII fields
const analytics = usePrivacyCompliant({
  customPiiFields: ["user_id", "email", "phone"]
});

// Update PII fields dynamically
const handleAddPiiField = (field: string) => {
  const currentFields = analytics.settings.customPiiFields;
  analytics.updateCustomPiiFields([...currentFields, field]);
};

// Remove PII field
const handleRemovePiiField = (field: string) => {
  const currentFields = analytics.settings.customPiiFields;
  analytics.updateCustomPiiFields(currentFields.filter(f => f !== field));
};

Best Practices

// ❌ Don't track without consent
analytics.trackEvent("sensitive_action", { userId: "123" });

// ✅ Check consent first
if (analytics.hasConsentFor(["analytics"])) {
  analytics.trackEvent("sensitive_action", { userId: "123" });
}
useEffect(() => {
  if (!analytics.consentState.hasConsent) {
    // Stop tracking when consent is withdrawn
    analytics.anonymizeData();
  }
}, [analytics.consentState.hasConsent]);

3. Configure Custom PII Fields

// Set up PII fields that should be anonymized
analytics.updateCustomPiiFields([
  "user_id",
  "email", 
  "phone",
  "ssn",
  "creditCard",
  "address"
]);

4. Handle Anonymization Preferences

// Allow users to control their anonymization preference
const handleAnonymizationToggle = (wantsAnonymized: boolean) => {
  analytics.updateAnonymizationPreference(wantsAnonymized);
  
  if (wantsAnonymized) {
    // Anonymize existing data when user enables anonymization
    analytics.anonymizeData();
  }
};