SDK & Installation

Add the Privacy Labs consent banner to your website with a single script tag. Configure behavior with data attributes.

Basic Installation

Add this script tag just before the closing </body> tag:

HTML
<script
  src="https://theprivacylabs.com/sdk/consent-banner.js"
  data-org="YOUR_ORG_SLUG"
  async
></script>

Configuration Attributes

AttributeRequiredDescription
data-orgYesYour organization slug from the dashboard
data-auto-initNoSet to "false" to manually initialize. Default: "true"
data-gtm-enabledNoEnable Google Tag Manager integration. Default: "false"

Framework Guides

Next.js (App Router)

Add the script to your root layout:

app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script
          src="https://theprivacylabs.com/sdk/consent-banner.js"
          data-org="YOUR_ORG_SLUG"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

React (Create React App / Vite)

Add the script to your index.html:

public/index.html
<!DOCTYPE html>
<html>
  <head>...</head>
  <body>
    <div id="root"></div>
    <script
      src="https://theprivacylabs.com/sdk/consent-banner.js"
      data-org="YOUR_ORG_SLUG"
      async
    ></script>
  </body>
</html>

Plain HTML

Add the script before the closing body tag:

<!DOCTYPE html>
<html>
  <head>...</head>
  <body>
    <!-- Your content -->
    <script
      src="https://theprivacylabs.com/sdk/consent-banner.js"
      data-org="YOUR_ORG_SLUG"
      async
    ></script>
  </body>
</html>

Shopify

Add the script to your theme's theme.liquid file:

  1. Go to Online Store → Themes → Edit code
  2. Open theme.liquid
  3. Add the script just before </body>
theme.liquid
<script
  src="https://theprivacylabs.com/sdk/consent-banner.js"
  data-org="YOUR_ORG_SLUG"
  async
></script>
</body>
</html>

WordPress

Add the script using your theme's functions.php or a plugin like "Insert Headers and Footers":

functions.php
function add_privacy_labs_consent() {
  ?>
  <script
    src="https://theprivacylabs.com/sdk/consent-banner.js"
    data-org="YOUR_ORG_SLUG"
    async
  ></script>
  <?php
}
add_action('wp_footer', 'add_privacy_labs_consent');

Or use a plugin: Go to Settings → Insert Headers and Footers and paste the script in the Footer section.

Google Tag Manager (GTM)

If you use Google Tag Manager, enable the GTM integration to sync consent with Google Consent Mode v2:

<script
  src="https://theprivacylabs.com/sdk/consent-banner.js"
  data-org="YOUR_ORG_SLUG"
  data-gtm-enabled="true"
  async
></script>

What happens when enabled: When a user gives consent, the SDK calls gtag('consent', 'update', ...) to update Google Consent Mode:

  • analytics_storage → granted/denied based on Analytics consent
  • ad_storage → granted/denied based on Marketing consent
  • ad_user_data → granted/denied based on Marketing consent
  • ad_personalization → granted/denied based on Marketing consent

It also pushes a consent_update event to the dataLayer for GTM triggers.

Note: Make sure GTM is loaded on your page and gtag is available before consent is given.

SDK Methods

The SDK exposes methods on window.PrivacyLabs:

init(config)

Manually initialize the banner (if data-auto-init="false")

window.theprivacylabs.comit({ org: 'acme-corp' })

getSessionId()

Get the current session ID for consent tracking

const sessionId = window.PrivacyLabs.getSessionId()

withdrawConsent()

Withdraw all consent and show the banner again

window.PrivacyLabs.withdrawConsent()

linkIdentity(userId)

Link consent to a logged-in user ID

window.PrivacyLabs.linkIdentity('user_123')

Mobile SDK

DPDP Act 2023 compliant consent management for iOS and Android apps using React Native or Flutter.

Key Difference from Web

On web, our script handles everything automatically — banner UI, consent state, API sync, GTM integration. On mobile, the SDK provides state management and API sync only. You must build your own consent banner and privacy settings screen.

What We Handle vs What You Build

ResponsibilitySDK (We Handle)Client (You Build)
Consent state management
API sync (record consent to server)
Cross-device consent sync
Consent categories & translations
Withdraw consent logic
Consent banner / bottom sheet UIYou build
Privacy settings screen UIYou build
Gate third-party SDKs based on consentYou build

1. Installation

React Native

Terminal
npm install @theprivacylabs/react-native-consent @react-native-async-storage/async-storage

Flutter

Terminal
flutter pub add theprivacylabs_consent

2. Initialize the SDK

Add to your App.tsx:

App.tsx (React Native)
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',
      onConsentChange: (consent) => {
        // Enable/disable SDKs based on consent
        if (consent.preferences.analytics) {
          Analytics.enable();
        } else {
          Analytics.disable();
        }
      },
    }, AsyncStorage);
  }, []);

  return <NavigationContainer>...</NavigationContainer>;
};
main.dart (Flutter)
import 'package:theprivacylabs_consent/theprivacylabs_consent.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await PrivacyLabsConsent.init(
    orgId: 'YOUR_ORG_ID',
    onConsentChange: (state) async {
      if (state.preferences['analytics'] == true) {
        await FirebaseAnalytics.instance
          .setAnalyticsCollectionEnabled(true);
      } else {
        await FirebaseAnalytics.instance
          .setAnalyticsCollectionEnabled(false);
      }
    },
  );

  runApp(MyApp());
}

3. Build a Consent Banner

You must build your own consent banner UI. Show it on first launch before any analytics/marketing SDK fires.

ConsentBanner.tsx
import { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, Modal } from 'react-native';
import { PrivacyLabsConsent } from '@theprivacylabs/react-native-consent';

const ConsentBanner = ({ navigation }) => {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    PrivacyLabsConsent.getConsentStatus().then((status) => {
      if (!status?.hasConsent) {
        setVisible(true);
      }
    });
  }, []);

  const handleAcceptAll = async () => {
    await PrivacyLabsConsent.acceptAll();
    setVisible(false);
  };

  const handleCustomize = () => {
    setVisible(false);
    navigation.navigate('PrivacySettings');
  };

  if (!visible) return null;

  return (
    <Modal transparent animationType="slide">
      <View style={{ flex: 1, justifyContent: 'flex-end' }}>
        <View style={{
          backgroundColor: '#fff',
          padding: 24,
          borderTopLeftRadius: 16,
          borderTopRightRadius: 16,
          shadowColor: '#000',
          shadowOpacity: 0.15,
          shadowRadius: 10,
          elevation: 10,
        }}>
          <Text style={{ fontSize: 18, fontWeight: 'bold', marginBottom: 8 }}>
            We Respect Your Privacy
          </Text>
          <Text style={{ color: '#666', marginBottom: 16, lineHeight: 20 }}>
            We use data collection to improve your experience.
            You can customize your preferences or accept all.
          </Text>
          <TouchableOpacity
            onPress={() => { /* Open privacy policy URL */ }}
            style={{ marginBottom: 16 }}
          >
            <Text style={{ color: '#2563eb', fontSize: 13 }}>
              Read our Privacy Policy
            </Text>
          </TouchableOpacity>
          <View style={{ flexDirection: 'row', gap: 12 }}>
            <TouchableOpacity
              onPress={handleCustomize}
              style={{
                flex: 1, padding: 14, borderRadius: 8,
                borderWidth: 1, borderColor: '#d1d5db',
                alignItems: 'center',
              }}
            >
              <Text style={{ fontWeight: '600' }}>Customize</Text>
            </TouchableOpacity>
            <TouchableOpacity
              onPress={handleAcceptAll}
              style={{
                flex: 1, padding: 14, borderRadius: 8,
                backgroundColor: '#2563eb', alignItems: 'center',
              }}
            >
              <Text style={{ color: '#fff', fontWeight: '600' }}>
                Accept All
              </Text>
            </TouchableOpacity>
          </View>
        </View>
      </View>
    </Modal>
  );
};

DPDP Act 2023 Banner Requirements

  • 1.Clear purpose statement — Tell the user what data you collect and why
  • 2.Accept All button — One-tap consent for all categories
  • 3.Customize option — Let users choose individual categories
  • 4.Link to Privacy Policy — Must be accessible before consent
  • 5.No pre-checked optional categories — Analytics/marketing must default to OFF
  • 6.Easy withdrawal — Privacy settings screen accessible from app settings

4. Build a Privacy Settings Screen

This screen lets users manage their consent after initial consent. Link to it from your app's Settings screen.

PrivacySettings.tsx
import { useConsent, useConsentCategories } from '@theprivacylabs/react-native-consent';
import { View, Text, Switch, ScrollView, TouchableOpacity } from 'react-native';

const PrivacySettings = () => {
  const { consent, setConsent, acceptAll, withdrawConsent } = useConsent();
  const { categories } = useConsentCategories('en');

  return (
    <ScrollView style={{ padding: 16 }}>
      <Text style={{ fontSize: 20, fontWeight: 'bold', marginBottom: 16 }}>
        Privacy Preferences
      </Text>

      {categories.map((cat) => (
        <View key={cat.id} style={{
          flexDirection: 'row', justifyContent: 'space-between',
          paddingVertical: 12, borderBottomWidth: 1, borderColor: '#eee',
        }}>
          <View style={{ flex: 1 }}>
            <Text style={{ fontWeight: '600' }}>{cat.name}</Text>
            <Text style={{ color: '#666', fontSize: 13 }}>{cat.description}</Text>
            {cat.required && (
              <Text style={{ color: '#999', fontSize: 11 }}>Always active</Text>
            )}
          </View>
          <Switch
            value={consent?.preferences[cat.id] ?? false}
            disabled={cat.required}
            onValueChange={(v) => setConsent({ [cat.id]: v })}
          />
        </View>
      ))}

      <TouchableOpacity
        onPress={acceptAll}
        style={{
          backgroundColor: '#2563eb', padding: 14,
          borderRadius: 8, marginTop: 20, alignItems: 'center',
        }}
      >
        <Text style={{ color: '#fff', fontWeight: '600' }}>Accept All</Text>
      </TouchableOpacity>

      <TouchableOpacity
        onPress={withdrawConsent}
        style={{
          borderWidth: 1, borderColor: '#dc2626', padding: 14,
          borderRadius: 8, marginTop: 12, alignItems: 'center',
        }}
      >
        <Text style={{ color: '#dc2626', fontWeight: '600' }}>
          Withdraw Consent
        </Text>
      </TouchableOpacity>
    </ScrollView>
  );
};

5. Link Identity After Login

Enable cross-device consent sync by linking user identity after login:

// After user logs in
await PrivacyLabsConsent.linkIdentity(userEmail, 'login');

// After user signs up
await PrivacyLabsConsent.linkIdentity(userEmail, 'signup');

When users log in on a new device, their consent preferences are automatically synced across web and mobile.

6. Gate Third-Party SDKs

Important: Mobile SDKs are compiled into your app — you cannot block them at runtime like web scripts. Instead, use consent state to enable/disable data collection in each SDK.

React Native
// Firebase Analytics
import analytics from '@react-native-firebase/analytics';

onConsentChange: async (state) => {
  await analytics().setAnalyticsCollectionEnabled(
    state.preferences.analytics
  );
}

// Mixpanel
consent.preferences.analytics
  ? mixpanel.optInTracking()
  : mixpanel.optOutTracking();

// Adjust (Marketing Attribution)
Adjust.setEnabled(consent.preferences.marketing);

// AppsFlyer
consent.preferences.marketing
  ? appsFlyer.startSdk()
  : appsFlyer.stop(true);

// Consent-gated helper pattern
async function ifConsented(category, action) {
  const ok = await PrivacyLabsConsent.hasConsent(category);
  if (ok) await action();
}
await ifConsented('analytics', () =>
  analytics().logEvent('purchase', { value: 99 })
);

Mobile SDK API Reference

PrivacyLabsConsent.init(config, storage?)

Initialize the SDK. Must be called before any other method.

PrivacyLabsConsent.getConsentStatus()

Returns current consent state or null if no consent given yet.

PrivacyLabsConsent.acceptAll()

Accept all consent categories and record to server.

PrivacyLabsConsent.setConsent(preferences)

Set individual category preferences. Example: { analytics: true, marketing: false }

PrivacyLabsConsent.withdrawConsent()

Withdraw all consent. Clears local storage and records withdrawal to server.

PrivacyLabsConsent.hasConsent(category)

Check if a specific category is consented. Returns boolean.

PrivacyLabsConsent.linkIdentity(email, event)

Link user identity for cross-device consent sync.

useConsent() React Native hook

Returns { consent, setConsent, acceptAll, withdrawConsent }

useConsentCategories(locale) React Native hook

Returns { categories } with localized names and descriptions.

DPDP Act 2023 Mobile Compliance Checklist

Show consent banner on first launch, before any analytics/marketing SDK fires

Banner explains what data is collected and why

Users can accept/reject individual categories (essential, analytics, marketing)

Optional categories default to OFF (no pre-checked boxes)

Privacy Settings screen accessible from app settings

Add a "Withdraw Consent" button in privacy settings

Link to Privacy Policy from banner and settings

If app targets children (<18), obtain verifiable parental consent

Call linkIdentity() after login for cross-device consent sync

Gate all analytics/marketing SDKs — only enable after consent is granted

Troubleshooting

Banner not showing? (Web)

Check that your org slug is correct and the domain is whitelisted in your dashboard.

Mobile SDK not syncing? (Mobile)

Ensure you pass the correct orgId from your dashboard and that AsyncStorage (React Native) or SharedPreferences (Flutter) is properly configured.

Test in incognito / fresh install

Use incognito mode (web) or a fresh app install (mobile) to see the consent flow as a first-time user.