tessl install tessl/npm-posthog-js@1.335.0PostHog Browser JS Library is a comprehensive browser analytics and feature management SDK that enables developers to capture user events, track product analytics, manage feature flags, record session replays, and implement feedback mechanisms like surveys and conversations in web applications.
Privacy and consent management allows you to control tracking, respect user preferences, and comply with privacy regulations like GDPR and CCPA.
Opts the user into tracking and data capture.
/**
* Opts the user into tracking
* @param options - Options for opt-in behavior
*/
function opt_in_capturing(options?: {
captureEventName?: EventName | null | false;
captureProperties?: Properties;
}): void;Usage Examples:
// Basic opt-in
posthog.opt_in_capturing();
// Opt-in with custom event
posthog.opt_in_capturing({
captureEventName: 'user_opted_in',
captureProperties: {
opt_in_method: 'cookie_banner',
timestamp: Date.now()
}
});
// Opt-in without capturing event
posthog.opt_in_capturing({
captureEventName: false
});
// Opt-in with consent categories
posthog.opt_in_capturing({
captureEventName: 'consent_granted',
captureProperties: {
consent_analytics: true,
consent_marketing: true,
consent_preferences: true
}
});Opts the user out of tracking and data capture.
/**
* Opts the user out of tracking
* Stops all event capture and deletes local data
*/
function opt_out_capturing(): void;Usage Examples:
// Opt out
posthog.opt_out_capturing();
// Opt out on user request
function onUserOptOut() {
posthog.opt_out_capturing();
showConfirmation('You have been opted out of tracking');
}
// Opt out with cleanup
function optOutAndClean() {
posthog.opt_out_capturing();
posthog.reset(true); // Also reset device ID
}Checks if the user has explicitly opted in to tracking.
/**
* Checks if the user has opted in to tracking
* @returns True if user has opted in, false otherwise
*/
function has_opted_in_capturing(): boolean;Usage Examples:
// Check opt-in status
if (posthog.has_opted_in_capturing()) {
console.log('User has opted in');
}
// Conditional tracking
function trackUserAction(action) {
if (posthog.has_opted_in_capturing()) {
posthog.capture(action);
}
}
// UI state
function ConsentBanner() {
const hasOptedIn = posthog.has_opted_in_capturing();
return hasOptedIn ? null : <ConsentPrompt />;
}Checks if the user has explicitly opted out of tracking.
/**
* Checks if the user has opted out of tracking
* @returns True if user has opted out, false otherwise
*/
function has_opted_out_capturing(): boolean;Usage Examples:
// Check opt-out status
if (posthog.has_opted_out_capturing()) {
console.log('User has opted out');
}
// Prevent tracking
function captureIfAllowed(event, properties) {
if (!posthog.has_opted_out_capturing()) {
posthog.capture(event, properties);
}
}
// Show privacy status
function PrivacyStatus() {
const hasOptedOut = posthog.has_opted_out_capturing();
return (
<div>
Tracking: {hasOptedOut ? 'Disabled' : 'Enabled'}
</div>
);
}Gets the explicit consent status (granted, denied, or pending).
/**
* Gets the explicit consent status
* @returns 'granted' if opted in, 'denied' if opted out, 'pending' if neither
*/
function get_explicit_consent_status(): 'granted' | 'denied' | 'pending';Usage Examples:
// Get consent status
const status = posthog.get_explicit_consent_status();
console.log('Consent status:', status);
// Handle all states
switch (posthog.get_explicit_consent_status()) {
case 'granted':
initializeAllFeatures();
break;
case 'denied':
showMinimalFeatures();
break;
case 'pending':
showConsentBanner();
break;
}
// Conditional feature initialization
function initializeFeatures() {
const consent = posthog.get_explicit_consent_status();
if (consent === 'granted') {
posthog.startSessionRecording();
posthog.startExceptionAutocapture();
} else if (consent === 'pending') {
// Wait for user decision
waitForConsent();
}
}Checks if capturing is currently enabled (not opted out).
/**
* Checks if capturing is currently enabled
* @returns True if capturing is active, false otherwise
*/
function is_capturing(): boolean;Usage Examples:
// Check if capturing
if (posthog.is_capturing()) {
console.log('Capturing is active');
}
// Conditional operations
function performTrackedOperation() {
const result = doOperation();
if (posthog.is_capturing()) {
posthog.capture('operation_completed');
}
return result;
}
// Debug logging
if (!posthog.is_capturing()) {
console.warn('PostHog capturing is disabled');
}Clears the opt-in/out status, resetting to default behavior.
/**
* Clears the opt-in/out status
* Resets to default capturing behavior based on config
*/
function clear_opt_in_out_capturing(): void;Usage Examples:
// Clear status
posthog.clear_opt_in_out_capturing();
// Reset consent state
function resetConsent() {
posthog.clear_opt_in_out_capturing();
showConsentBanner();
}
// Allow user to change decision
function changeConsentPreference() {
posthog.clear_opt_in_out_capturing();
// User can now choose again
promptForConsent();
}Configure PostHog to start with capturing disabled:
// Require opt-in before capturing
posthog.init('token', {
opt_out_capturing_by_default: true
});
// User must explicitly opt in
// posthog.opt_in_capturing();
// Also disable persistence by default
posthog.init('token', {
opt_out_capturing_by_default: true,
opt_out_persistence_by_default: true
});Respect the browser's Do Not Track setting:
posthog.init('token', {
respect_dnt: true
});Configure cookieless tracking:
// Never use cookies/storage
posthog.init('token', {
cookieless_mode: 'always'
});
// Use cookies unless user rejects
posthog.init('token', {
cookieless_mode: 'on_reject'
});
// Always use cookies (default)
posthog.init('token', {
cookieless_mode: 'never'
});Prevent specific properties from being captured:
posthog.init('token', {
property_denylist: [
'password',
'credit_card',
'ssn',
'api_key',
'secret'
]
});Automatically mask personal data properties:
posthog.init('token', {
mask_personal_data_properties: true,
custom_personal_data_properties: [
'email',
'phone',
'address',
'name'
]
});Implement GDPR-compliant consent:
// Initialize with opt-out by default
posthog.init('token', {
opt_out_capturing_by_default: true,
opt_out_persistence_by_default: true
});
// Show consent banner
function showConsentBanner() {
const banner = document.createElement('div');
banner.innerHTML = `
<div class="consent-banner">
<p>We use cookies for analytics. Accept?</p>
<button id="accept">Accept</button>
<button id="reject">Reject</button>
</div>
`;
document.getElementById('accept').addEventListener('click', () => {
posthog.opt_in_capturing({
captureEventName: 'gdpr_consent_granted'
});
banner.remove();
});
document.getElementById('reject').addEventListener('click', () => {
posthog.opt_out_capturing();
banner.remove();
});
document.body.appendChild(banner);
}
// Check consent on page load
if (posthog.get_explicit_consent_status() === 'pending') {
showConsentBanner();
}Implement CCPA "Do Not Sell" option:
// Show "Do Not Sell My Personal Information" link
function showCCPALink() {
const link = document.createElement('a');
link.textContent = 'Do Not Sell My Personal Information';
link.href = '#';
link.addEventListener('click', (e) => {
e.preventDefault();
posthog.opt_out_capturing();
alert('You have opted out of personal information sale');
});
document.body.appendChild(link);
}
// Allow users to check and change status
function showPrivacyDashboard() {
const hasOptedOut = posthog.has_opted_out_capturing();
if (hasOptedOut) {
showOptInButton();
} else {
showOptOutButton();
}
}Implement consent for specific tracking features:
class ConsentManager {
constructor() {
this.consent = {
analytics: false,
advertising: false,
personalization: false,
sessionRecording: false,
errorTracking: false
};
}
updateConsent(category, granted) {
this.consent[category] = granted;
this.applyConsent();
}
applyConsent() {
// Basic analytics
if (this.consent.analytics) {
posthog.opt_in_capturing();
} else {
posthog.opt_out_capturing();
}
// Session recording
if (this.consent.sessionRecording) {
posthog.startSessionRecording();
} else {
posthog.stopSessionRecording();
}
// Error tracking
if (this.consent.errorTracking) {
posthog.startExceptionAutocapture();
} else {
posthog.stopExceptionAutocapture();
}
}
getConsentState() {
return { ...this.consent };
}
}
// Usage
const consentManager = new ConsentManager();
consentManager.updateConsent('analytics', true);
consentManager.updateConsent('sessionRecording', true);
consentManager.updateConsent('errorTracking', false);Build reusable consent components:
// React consent banner
function ConsentBanner() {
const [visible, setVisible] = useState(true);
useEffect(() => {
const status = posthog.get_explicit_consent_status();
if (status !== 'pending') {
setVisible(false);
}
}, []);
const handleAccept = () => {
posthog.opt_in_capturing({
captureEventName: 'consent_accepted'
});
setVisible(false);
};
const handleReject = () => {
posthog.opt_out_capturing();
setVisible(false);
};
if (!visible) return null;
return (
<div className="consent-banner">
<p>We use cookies to improve your experience.</p>
<button onClick={handleAccept}>Accept</button>
<button onClick={handleReject}>Reject</button>
</div>
);
}
// Privacy settings page
function PrivacySettings() {
const [capturing, setCapturing] = useState(posthog.is_capturing());
const handleToggle = () => {
if (capturing) {
posthog.opt_out_capturing();
setCapturing(false);
} else {
posthog.opt_in_capturing();
setCapturing(true);
}
};
return (
<div>
<h2>Privacy Settings</h2>
<label>
<input
type="checkbox"
checked={capturing}
onChange={handleToggle}
/>
Enable Analytics
</label>
</div>
);
}Integrate with cookie consent libraries:
// OneTrust integration
window.OptanonWrapper = function() {
const activeGroups = window.OnetrustActiveGroups;
// Check if analytics cookies are accepted
if (activeGroups.includes('C0002')) {
posthog.opt_in_capturing({
captureEventName: 'onetrust_consent_granted'
});
} else {
posthog.opt_out_capturing();
}
};
// CookieBot integration
window.addEventListener('CookiebotOnAccept', function() {
if (Cookiebot.consent.statistics) {
posthog.opt_in_capturing({
captureEventName: 'cookiebot_consent_granted'
});
}
});
window.addEventListener('CookiebotOnDecline', function() {
posthog.opt_out_capturing();
});
// Google Consent Mode integration
function updatePostHogConsent(consentSettings) {
if (consentSettings.analytics_storage === 'granted') {
posthog.opt_in_capturing();
} else {
posthog.opt_out_capturing();
}
}
gtag('consent', 'default', {
analytics_storage: 'denied'
});
gtag('consent', 'update', {
analytics_storage: 'granted'
});
updatePostHogConsent({ analytics_storage: 'granted' });Load features based on consent:
async function initializeWithConsent() {
const consent = posthog.get_explicit_consent_status();
if (consent === 'pending') {
// Wait for user decision
await promptForConsent();
}
if (posthog.has_opted_in_capturing()) {
// Load full features
posthog.startSessionRecording();
posthog.startExceptionAutocapture();
// Load analytics-dependent features
await loadUserRecommendations();
await loadPersonalizedContent();
} else {
// Load minimal features
showGenericContent();
}
}Implement consent expiration:
const CONSENT_EXPIRY_DAYS = 365;
function setConsentWithExpiry(granted) {
const expiry = Date.now() + (CONSENT_EXPIRY_DAYS * 24 * 60 * 60 * 1000);
localStorage.setItem('consent_expiry', expiry.toString());
if (granted) {
posthog.opt_in_capturing();
} else {
posthog.opt_out_capturing();
}
}
function checkConsentExpiry() {
const expiry = localStorage.getItem('consent_expiry');
if (expiry && Date.now() > parseInt(expiry)) {
// Consent expired, reset
posthog.clear_opt_in_out_capturing();
localStorage.removeItem('consent_expiry');
showConsentBanner();
}
}
// Check on page load
checkConsentExpiry();Show consent based on user location:
async function initializeWithGeolocation() {
const country = await getUserCountry();
const gdprCountries = ['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB'];
if (gdprCountries.includes(country)) {
// Require explicit consent for GDPR countries
posthog.init('token', {
opt_out_capturing_by_default: true
});
if (posthog.get_explicit_consent_status() === 'pending') {
showGDPRConsentBanner();
}
} else {
// Auto opt-in for non-GDPR countries (with opt-out option)
posthog.init('token', {
opt_out_capturing_by_default: false
});
showOptOutLink();
}
}Track consent changes for audit:
function trackConsentChange(oldStatus, newStatus) {
// Log to backend for compliance
fetch('/api/consent-log', {
method: 'POST',
body: JSON.stringify({
user_id: posthog.get_distinct_id(),
old_status: oldStatus,
new_status: newStatus,
timestamp: Date.now(),
user_agent: navigator.userAgent
})
});
}
function optInWithTracking() {
const oldStatus = posthog.get_explicit_consent_status();
posthog.opt_in_capturing({
captureEventName: 'consent_granted'
});
const newStatus = posthog.get_explicit_consent_status();
trackConsentChange(oldStatus, newStatus);
}
function optOutWithTracking() {
const oldStatus = posthog.get_explicit_consent_status();
posthog.opt_out_capturing();
const newStatus = posthog.get_explicit_consent_status();
trackConsentChange(oldStatus, newStatus);
}Initialize with maximum privacy by default:
posthog.init('token', {
// Require opt-in
opt_out_capturing_by_default: true,
opt_out_persistence_by_default: true,
// Respect browser settings
respect_dnt: true,
// Cookieless mode
cookieless_mode: 'always',
// Disable features by default
disable_session_recording: true,
capture_exceptions: false,
autocapture: false,
// Mask all data
mask_all_text: true,
mask_all_element_attributes: true,
property_denylist: [
'email', 'name', 'phone', 'address',
'credit_card', 'ssn', 'password'
]
});
// Enable features after consent
function onUserConsent() {
posthog.opt_in_capturing();
posthog.set_config({
autocapture: true,
capture_exceptions: true
});
posthog.startSessionRecording();
}Persist consent across sessions:
class ConsentStorage {
static save(status) {
localStorage.setItem('posthog_consent', status);
localStorage.setItem('posthog_consent_date', Date.now().toString());
}
static load() {
return localStorage.getItem('posthog_consent');
}
static getDate() {
return localStorage.getItem('posthog_consent_date');
}
static clear() {
localStorage.removeItem('posthog_consent');
localStorage.removeItem('posthog_consent_date');
}
}
// Initialize with saved consent
function initializeWithSavedConsent() {
const savedConsent = ConsentStorage.load();
if (savedConsent === 'granted') {
posthog.opt_in_capturing();
} else if (savedConsent === 'denied') {
posthog.opt_out_capturing();
} else {
// No saved consent, show banner
showConsentBanner();
}
}
// Save when consent changes
function handleConsentChange(granted) {
if (granted) {
posthog.opt_in_capturing();
ConsentStorage.save('granted');
} else {
posthog.opt_out_capturing();
ConsentStorage.save('denied');
}
}// Handle different privacy laws by region
interface RegionConfig {
requiresExplicitConsent: boolean;
dataResidency: 'us' | 'eu';
retentionDays: number;
}
const regionConfigs: Record<string, RegionConfig> = {
'US': { requiresExplicitConsent: false, dataResidency: 'us', retentionDays: 730 },
'GB': { requiresExplicitConsent: true, dataResidency: 'eu', retentionDays: 365 },
'DE': { requiresExplicitConsent: true, dataResidency: 'eu', retentionDays: 365 },
'FR': { requiresExplicitConsent: true, dataResidency: 'eu', retentionDays: 365 }
};
async function initializeWithRegionalCompliance() {
const userRegion = await detectUserRegion();
const config = regionConfigs[userRegion] || regionConfigs['US'];
const apiHost = config.dataResidency === 'eu'
? 'https://eu.i.posthog.com'
: 'https://us.i.posthog.com';
posthog.init('token', {
api_host: apiHost,
opt_out_capturing_by_default: config.requiresExplicitConsent
});
if (config.requiresExplicitConsent) {
const consent = getStoredConsent();
if (!consent) {
showConsentBanner();
} else if (consent === 'granted') {
posthog.opt_in_capturing();
}
}
}// OneTrust CMP integration
declare global {
interface Window {
OneTrust?: {
OnConsentChanged: (callback: () => void) => void;
};
OnetrustActiveGroups?: string;
}
}
function initializeOneTrustIntegration() {
// Check initial consent
const checkConsent = () => {
const activeGroups = window.OnetrustActiveGroups || '';
const analyticsConsent = activeGroups.includes('C0002');
if (analyticsConsent) {
posthog.opt_in_capturing({
captureEventName: 'onetrust_consent_granted',
captureProperties: {
consent_groups: activeGroups
}
});
} else {
posthog.opt_out_capturing();
}
};
// Check on load
checkConsent();
// Listen for changes
window.OneTrust?.OnConsentChanged(() => {
checkConsent();
});
}// Implement CCPA "Do Not Sell" functionality
class CCPACompliance {
private readonly DO_NOT_SELL_KEY = 'ccpa_do_not_sell';
initialize() {
// Check if user has opted out of sale
const doNotSell = localStorage.getItem(this.DO_NOT_SELL_KEY) === 'true';
if (doNotSell) {
this.optOutOfSale();
}
// Add "Do Not Sell" link to footer
this.addDoNotSellLink();
}
optOutOfSale() {
// Opt out of tracking
posthog.opt_out_capturing();
// Store preference
localStorage.setItem(this.DO_NOT_SELL_KEY, 'true');
// Capture opt-out event before disabling
posthog.capture('ccpa_do_not_sell', {
opted_out_at: new Date().toISOString()
});
}
optInToSale() {
// Opt back in
posthog.opt_in_capturing({
captureEventName: 'ccpa_sale_opted_in'
});
// Clear preference
localStorage.removeItem(this.DO_NOT_SELL_KEY);
}
addDoNotSellLink() {
const link = document.createElement('a');
link.href = '#';
link.textContent = 'Do Not Sell My Personal Information';
link.className = 'ccpa-opt-out-link';
link.addEventListener('click', (e) => {
e.preventDefault();
this.showOptOutModal();
});
document.querySelector('.footer')?.appendChild(link);
}
showOptOutModal() {
const confirmed = confirm(
'You are about to opt out of the sale of your personal information. Continue?'
);
if (confirmed) {
this.optOutOfSale();
alert('You have successfully opted out.');
}
}
}// Disable tracking for users under 13
function initializeCOPPACompliance(userAge?: number) {
if (userAge && userAge < 13) {
posthog.init('token', {
// Completely disable tracking for children
opt_out_capturing_by_default: true,
opt_out_persistence_by_default: true,
disable_persistence: true,
disable_session_recording: true,
disable_surveys: true,
autocapture: false,
capture_pageview: false
});
// Ensure opt-out is persistent
posthog.opt_out_capturing();
console.log('COPPA compliance mode: Tracking disabled for user under 13');
} else {
// Normal initialization for adults
posthog.init('token', {
opt_out_capturing_by_default: true
});
// Show age-appropriate consent
showAdultConsentBanner();
}
}// Provide user access to their data
async function getUserData() {
const distinctId = posthog.get_distinct_id();
const groups = posthog.getGroups();
return {
distinct_id: distinctId,
groups: groups,
// Note: Full data export must be done via PostHog API
posthog_profile_url: `https://app.posthog.com/person/${distinctId}`
};
}// Handle deletion request
async function handleDeletionRequest(userId: string) {
// Reset local state
posthog.reset(true); // Reset including device ID
// Opt out to prevent future tracking
posthog.opt_out_capturing();
// Clear all local storage
Object.keys(localStorage).forEach(key => {
if (key.startsWith('ph_')) {
localStorage.removeItem(key);
}
});
// Log deletion request for backend processing
await logDeletionRequest(userId);
console.log('User data deletion initiated');
}// Update incorrect user properties
async function rectifyUserData(corrections: Properties) {
// Update properties in PostHog
posthog.setPersonProperties(corrections);
// Log rectification for audit trail
posthog.capture('data_rectified', {
rectified_fields: Object.keys(corrections),
rectified_at: new Date().toISOString()
});
}// Export user data in portable format
async function exportUserData() {
const userData = {
distinct_id: posthog.get_distinct_id(),
groups: posthog.getGroups(),
session_id: posthog.get_session_id(),
feature_flags: posthog.featureFlags.getFlagVariants(),
// Note: Full event history requires PostHog API access
export_date: new Date().toISOString()
};
// Convert to JSON for portability
const dataBlob = new Blob(
[JSON.stringify(userData, null, 2)],
{ type: 'application/json' }
);
// Download file
const url = URL.createObjectURL(dataBlob);
const link = document.createElement('a');
link.href = url;
link.download = `posthog-data-${userData.distinct_id}.json`;
link.click();
URL.revokeObjectURL(url);
}class ConsentLifecycleManager {
private readonly CONSENT_VERSION = '2.0';
initialize() {
const stored = this.getStoredConsent();
if (!stored || stored.version !== this.CONSENT_VERSION) {
// No consent or version changed, show banner
this.showConsentBanner();
} else {
// Apply stored consent
this.applyConsent(stored.granted);
}
}
showConsentBanner() {
// Show UI with granular options
const banner = this.createGranularConsentUI({
onSave: (choices) => {
this.saveConsent(choices);
this.applyConsent(choices.analytics);
}
});
}
saveConsent(choices: {
analytics: boolean;
marketing: boolean;
functional: boolean;
}) {
const consent = {
version: this.CONSENT_VERSION,
granted: choices.analytics,
choices: choices,
timestamp: new Date().toISOString()
};
localStorage.setItem('posthog_consent', JSON.stringify(consent));
}
getStoredConsent(): {
version: string;
granted: boolean;
choices: any;
timestamp: string;
} | null {
const stored = localStorage.getItem('posthog_consent');
return stored ? JSON.parse(stored) : null;
}
applyConsent(granted: boolean) {
if (granted) {
posthog.opt_in_capturing({
captureEventName: 'consent_applied',
captureProperties: {
consent_version: this.CONSENT_VERSION
}
});
} else {
posthog.opt_out_capturing();
}
}
revokeConsent() {
// Revoke consent and delete data
posthog.opt_out_capturing();
posthog.reset(true);
localStorage.removeItem('posthog_consent');
console.log('Consent revoked and data cleared');
}
createGranularConsentUI(options: any) {
// Implementation of granular consent UI
// Returns banner element
}
}describe('Privacy Compliance', () => {
it('requires opt-in before tracking', () => {
posthog.init('token', {
opt_out_capturing_by_default: true
});
expect(posthog.is_capturing()).toBe(false);
posthog.opt_in_capturing();
expect(posthog.is_capturing()).toBe(true);
});
it('respects Do Not Track', () => {
// Mock DNT
Object.defineProperty(navigator, 'doNotTrack', {
value: '1',
configurable: true
});
posthog.init('token', {
respect_dnt: true
});
expect(posthog.is_capturing()).toBe(false);
});
it('deletes data on opt-out', () => {
posthog.init('token');
posthog.identify('user-123');
const distinctIdBefore = posthog.get_distinct_id();
posthog.opt_out_capturing();
// Should clear local data
expect(posthog.is_capturing()).toBe(false);
});
});// Debug consent persistence
function debugConsent() {
console.log('Consent status:', posthog.get_explicit_consent_status());
console.log('Has opted in:', posthog.has_opted_in_capturing());
console.log('Has opted out:', posthog.has_opted_out_capturing());
console.log('Is capturing:', posthog.is_capturing());
// Check storage
console.log('Consent storage:', {
localStorage: localStorage.getItem('__ph_consent'),
cookie: document.cookie.includes('ph_consent')
});
// Check config
console.log('Config:', {
opt_out_by_default: posthog.config.opt_out_capturing_by_default,
consent_name: posthog.config.consent_persistence_name
});
}// Verify opt-out
function verifyOptOut() {
posthog.opt_out_capturing();
// Wait for state to update
setTimeout(() => {
console.log('Opt-out verification:', {
is_capturing: posthog.is_capturing(),
has_opted_out: posthog.has_opted_out_capturing(),
status: posthog.get_explicit_consent_status()
});
// Try capturing event (should fail)
const result = posthog.capture('test_event');
console.log('Capture after opt-out:', result); // Should be undefined or void
}, 100);
}// Force DNT respect
function enforceDNT() {
if (navigator.doNotTrack === '1' ||
(navigator as any).doNotTrack === 'yes' ||
(window as any).doNotTrack === '1') {
console.log('DNT detected, disabling tracking');
posthog.opt_out_capturing();
// Ensure it can't be overridden
const originalOptIn = posthog.opt_in_capturing;
posthog.opt_in_capturing = () => {
console.warn('Opt-in blocked due to DNT');
};
}
}// Full Cookiebot integration
declare global {
interface Window {
Cookiebot?: {
consent: {
necessary: boolean;
preferences: boolean;
statistics: boolean;
marketing: boolean;
};
consented: boolean;
};
}
}
function initializeCookiebotIntegration() {
posthog.init('token', {
opt_out_capturing_by_default: true
});
// Handle consent acceptance
window.addEventListener('CookiebotOnAccept', () => {
if (window.Cookiebot?.consent.statistics) {
posthog.opt_in_capturing({
captureEventName: 'cookiebot_consent_granted',
captureProperties: {
consent_preferences: window.Cookiebot.consent.preferences,
consent_marketing: window.Cookiebot.consent.marketing
}
});
// Enable features based on consent
if (window.Cookiebot.consent.statistics) {
posthog.startSessionRecording();
}
}
});
// Handle consent decline
window.addEventListener('CookiebotOnDecline', () => {
posthog.opt_out_capturing();
posthog.stopSessionRecording();
});
// Check if already consented
if (window.Cookiebot?.consented && window.Cookiebot?.consent.statistics) {
posthog.opt_in_capturing();
}
}// Usercentrics CMP integration
declare global {
interface Window {
UC_UI?: {
isInitialized: () => boolean;
getServicesBaseInfo: () => Array<{
id: string;
name: string;
consent: { status: boolean };
}>;
};
}
}
function initializeUsercentricsIntegration() {
const POSTHOG_SERVICE_ID = 'PostHog';
posthog.init('token', {
opt_out_capturing_by_default: true
});
// Wait for Usercentrics
const checkConsent = () => {
if (window.UC_UI?.isInitialized()) {
const services = window.UC_UI.getServicesBaseInfo();
const posthogService = services.find(s => s.name === POSTHOG_SERVICE_ID);
if (posthogService?.consent.status) {
posthog.opt_in_capturing({
captureEventName: 'usercentrics_consent_granted'
});
} else {
posthog.opt_out_capturing();
}
} else {
// Retry
setTimeout(checkConsent, 100);
}
};
checkConsent();
// Listen for consent changes
window.addEventListener('ucEvent', (event: any) => {
if (event.detail?.event === 'consent_status') {
checkConsent();
}
});
}Your privacy policy should disclose:
Analytics and Tracking
We use PostHog to understand how users interact with our application. PostHog collects:
- Page views and navigation patterns
- Button clicks and user interactions
- Device information (browser, OS, screen size)
- Session recordings (with sensitive data masked)
This data is processed by PostHog Inc. and stored in [US/EU] data centers. You can opt out of tracking at any time through our privacy settings.
For more information, see PostHog's privacy policy: https://posthog.com/privacy