@theprivacylabs/react-native-consent
v0.2.0
Published
DPDP-compliant consent management SDK for React Native apps
Downloads
29
Maintainers
Readme
@theprivacylabs/react-native-consent
DPDP-compliant consent management SDK for React Native apps.
Installation
npm install @theprivacylabs/react-native-consent @react-native-async-storage/async-storageQuick Start
1. Initialize the SDK
// App.tsx
import { PrivacyLabsConsent } from '@theprivacylabs/react-native-consent';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useEffect } from 'react';
const App = () => {
useEffect(() => {
PrivacyLabsConsent.init(
{
orgId: 'your-org-id', // From Privacy Labs dashboard
onConsentChange: (consent) => {
console.log('Consent changed:', consent);
// Enable/disable analytics based on consent
if (consent.preferences.analytics) {
Analytics.enable();
} else {
Analytics.disable();
}
},
onError: (error) => {
console.error('Consent error:', error);
},
debug: __DEV__, // Enable debug logs in development
},
AsyncStorage
);
}, []);
return <NavigationContainer>...</NavigationContainer>;
};2. Create Privacy Settings Screen
// PrivacySettingsScreen.tsx
import React, { useEffect, useState } from 'react';
import { View, Text, Switch, TouchableOpacity, ScrollView, ActivityIndicator } from 'react-native';
import { useConsent, useConsentCategories, PrivacyLabsConsent } from '@theprivacylabs/react-native-consent';
const PrivacySettingsScreen = () => {
const { consent, isLoading, setConsent, acceptAll } = useConsent();
const { categories } = useConsentCategories('en');
if (isLoading) {
return <ActivityIndicator size="large" />;
}
return (
<ScrollView style={{ flex: 1, padding: 16 }}>
<Text style={{ fontSize: 24, fontWeight: 'bold', marginBottom: 8 }}>
Privacy Settings
</Text>
<Text style={{ color: '#666', marginBottom: 24 }}>
Control how we use your data. You can change these settings at any time.
</Text>
{categories.map((category) => (
<View
key={category.id}
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 16,
borderBottomWidth: 1,
borderBottomColor: '#eee',
}}
>
<View style={{ flex: 1, marginRight: 16 }}>
<Text style={{ fontSize: 16, fontWeight: '600' }}>{category.name}</Text>
<Text style={{ color: '#666', marginTop: 4 }}>{category.description}</Text>
</View>
<Switch
value={consent?.preferences[category.id] ?? category.defaultEnabled}
disabled={category.required}
onValueChange={(value) => setConsent({ [category.id]: value })}
/>
</View>
))}
<View style={{ marginTop: 24, gap: 12 }}>
<TouchableOpacity
style={{
backgroundColor: '#2563eb',
padding: 16,
borderRadius: 8,
alignItems: 'center',
}}
onPress={acceptAll}
>
<Text style={{ color: 'white', fontWeight: '600' }}>Accept All</Text>
</TouchableOpacity>
</View>
</ScrollView>
);
};3. Link Identity After Login
// After user logs in
const handleLogin = async (email: string, password: string) => {
const user = await authService.login(email, password);
// Link consent to user identity for cross-device sync
await PrivacyLabsConsent.linkIdentity(email, 'login');
};
// After user signs up
const handleSignup = async (email: string, password: string) => {
const user = await authService.signup(email, password);
await PrivacyLabsConsent.linkIdentity(email, 'signup');
};4. iOS App Tracking Transparency (Optional)
For iOS apps that use tracking, you need to request ATT permission:
import { Platform } from 'react-native';
import { PrivacyLabsConsent } from '@theprivacylabs/react-native-consent';
const requestTrackingPermission = async () => {
if (Platform.OS === 'ios') {
// Request ATT permission first
const attStatus = await PrivacyLabsConsent.requestATTPermission();
if (attStatus === 'authorized') {
// User allowed tracking, show privacy settings
navigation.navigate('PrivacySettings');
} else {
// User denied tracking, set consent accordingly
await PrivacyLabsConsent.setConsent({
analytics: false,
marketing: false,
});
}
} else {
// Android: just show privacy settings
navigation.navigate('PrivacySettings');
}
};Note: ATT requires native module integration. Install react-native-tracking-transparency for full ATT support.
API Reference
PrivacyLabsConsent
| Method | Description |
|--------|-------------|
| init(config, asyncStorage) | Initialize the SDK |
| getConsentStatus(syncWithServer?) | Get current consent state |
| hasConsent(category) | Check if user consented to a category |
| getCategories(lang?) | Get available consent categories |
| setConsent(preferences) | Update consent preferences |
| acceptAll() | Accept all categories |
| withdrawConsent() | Withdraw all consent |
| linkIdentity(userKey, method?) | Link consent to user identity |
| syncFromServer(userId) | Sync consent from another device |
| requestATTPermission() | Request iOS ATT permission |
| getATTStatus() | Get iOS ATT status |
| clearLocalData() | Clear local consent data |
Hooks
useConsent()
const {
consent, // Current consent state
isLoading, // Loading state
error, // Error if any
hasConsent, // Check category consent
setConsent, // Update preferences
acceptAll, // Accept all
withdrawConsent,// Withdraw consent
refresh, // Refresh from server
} = useConsent();useConsentCategories(lang?)
const {
categories, // Array of ConsentCategory
isLoading, // Loading state
error, // Error if any
refresh, // Refresh categories
} = useConsentCategories('en');Cross-Device Consent Sync
When a user logs in on a new device, their consent preferences are automatically synced:
- User gives consent on Device A (web or mobile)
- User logs in on Device B (mobile app)
- SDK calls
linkIdentity()with user's email - Backend finds existing consent and syncs to Device B
onConsentChangecallback fires with synced preferences
This ensures consistent consent across all user devices.
Integration Checklist
Before Launch
- [ ] Install SDK and AsyncStorage
- [ ] Initialize SDK in App.tsx with orgId
- [ ] Create Privacy Settings screen with category toggles
- [ ] Add "Withdraw Consent" button that calls
withdrawConsent()(clears local data + records to API) - [ ] Add "Privacy Settings" to app settings/profile menu
On User Events
- [ ] First app launch: Check consent status, show settings if needed
- [ ] User login: Call
linkIdentity(email, 'login') - [ ] User signup: Call
linkIdentity(email, 'signup') - [ ] User logout: Optionally call
clearLocalData()
SDK Integration
- [ ] Gate analytics/marketing SDKs based on consent state
- [ ] Implement
onConsentChangecallback to enable/disable SDKs dynamically - [ ] See SDK Integration Recipes below for per-SDK examples
SDK Integration Recipes
Important: Mobile SDKs are compiled into your app — you cannot "not load" them at runtime. Instead, consent controls whether each SDK collects data or not. Your app owns execution; Privacy Labs owns consent state + policy.
Firebase Analytics
import analytics from '@react-native-firebase/analytics';
import { PrivacyLabsConsent } from '@theprivacylabs/react-native-consent';
// On app launch — set initial state
const consent = await PrivacyLabsConsent.getConsentStatus();
await analytics().setAnalyticsCollectionEnabled(consent?.preferences.analytics ?? false);
// On consent change — update dynamically
PrivacyLabsConsent.init({
orgId: 'your-org-id',
onConsentChange: async (state) => {
await analytics().setAnalyticsCollectionEnabled(state.preferences.analytics);
},
}, AsyncStorage);Firebase Crashlytics
import crashlytics from '@react-native-firebase/crashlytics';
// Gate on analytics (or performance) consent
await crashlytics().setCrashlyticsCollectionEnabled(consent?.preferences.analytics ?? false);Mixpanel
import { Mixpanel } from 'mixpanel-react-native';
const mixpanel = new Mixpanel('YOUR_TOKEN', true);
// On consent change
if (consent.preferences.analytics) {
mixpanel.optInTracking();
} else {
mixpanel.optOutTracking();
}Adjust (Marketing Attribution)
import { Adjust, AdjustConfig } from 'react-native-adjust';
const adjustConfig = new AdjustConfig('APP_TOKEN', AdjustConfig.EnvironmentProduction);
// Only enable if marketing consent given
if (consent?.preferences.marketing) {
Adjust.create(adjustConfig);
} else {
Adjust.setEnabled(false);
}
// On consent change
onConsentChange: (state) => {
Adjust.setEnabled(state.preferences.marketing);
}AppsFlyer
import appsFlyer from 'react-native-appsflyer';
// Gate on marketing consent
if (consent?.preferences.marketing) {
appsFlyer.startSdk();
} else {
appsFlyer.stop(true);
}CleverTap / MoEngage (Marketing Push)
// CleverTap
import CleverTap from 'clevertap-react-native';
if (consent?.preferences.marketing) {
CleverTap.setOptOut(false);
} else {
CleverTap.setOptOut(true);
}
// MoEngage
import ReactMoE from 'react-native-moengage';
if (consent?.preferences.marketing) {
ReactMoE.enableDataTracking();
} else {
ReactMoE.disableDataTracking();
}Pattern: Consent-Gated SDK Wrapper
// utils/consentGate.ts
import { PrivacyLabsConsent, ConsentPreferences } from '@theprivacylabs/react-native-consent';
export async function ifConsented(
category: keyof ConsentPreferences,
action: () => void | Promise<void>
): Promise<void> {
const hasConsent = await PrivacyLabsConsent.hasConsent(category);
if (hasConsent) {
await action();
}
}
// Usage
await ifConsented('analytics', () => analytics().logEvent('purchase', { value: 99 }));
await ifConsented('marketing', () => Adjust.trackEvent(adjustEvent));License
MIT
