React Native

The OneTrust React Native library is hosted on NPM.

Versioning and Installation

Versioning

The SDK version used in the app must match the version of the app data published from your OneTrust tenant. For example, if you've published version 202408.1.0 of the app data in your OneTrust environment, you must use npm package version 202408.1.0 as well. It is recommended to specify a version to avoid automatic updates, as a OneTrust publish is typically required when you update your SDK version.

📘

tvOS

As of 202403.1.3, our React Native package supports tvOS.

Installation

Example:

$ npm install [email protected]

$ cd ios && pod install

Android requirements

Ensure that the application supports RTL. Simply add android:supportsRtl="true" to the <application> element in your Android Manifest file.

Resolving Dependency Clashes in Android

The underling OneTrust Native SDK relies on a number of transitive dependencies to operate. If your app does not include these already, they'll be added by the OneTrust package. If they do already exist in your application, there may be a clash between the versions OneTrust requires and the versions your application is using. Add the below to the dependencies section of your :app Build.gradle file. Uncomment any transitive dependency that you would like to exclude, or uncomment the last line to exclude all transitive dependencies.

If your application excludes a dependency, it must be added elsewhere in your application.

implementation(project(":react-native-onetrust-cmp")){
//Uncomment any group that you'd like to exclude
//        exclude group: 'androidx.appcompat'
//        exclude group: 'androidx.constraintlayout'
//        exclude group: 'com.google.android.material'
//        exclude group: 'androidx.work'
//        exclude group: 'androidx.browser'
//        exclude group: 'com.github.bumptech.glide'
//        exclude group: 'com.squareup.retrofit2'

//Uncomment the next line to exclude all dependencies
//        transitive = false
}

Implementation and Development

The following sections are laid in in a typical order of development and UX.

Initializing the SDK

The OneTrust SDK retrieves an object that contains all the data needed to present a UI to a user to collect consent for the application. The data returned is determined by the configurations made in the OneTrust admin console.

Before proceeding, make sure that your SDK Data has been published inside of the OneTrust Admin Portal. If the data has not been published, the SDK will not have any data to retrieve. View instructions on how to publish here.

startSDK

This method is the initialization method for the SDK. It makes between 1-2 network calls:

  • 1 network call when using a non-IAB TCF template
  • 2 networks calls when using a IAB TCF template
OTPublishersNativeSDK.startSDK(
  'storageLocation',
  'domainIdentifier',
  'languageCode',
  {countryCode: 'us', regionCode:'ca'},
  true,
)
  .then((responseObject) => {
    console.info(`Download status is ${responseObject.status}`.);
    // get full JSON object from responseObject.responseString
  })
  .catch((error) => {
    console.error(`OneTrust download failed with error ${error}`);
  });
ArgumentTypeDescription
storageLocationStringThe CDN location for the JSON that the SDK fetches. (Usually, but not always, cdn.cookielaw.org.
domainIdentifierStringThe App ID to load
languageCodeString2-digit or 4-digit (in the case of advanced languages) ISO language code used to return content in a specific language.

Note: Any language code format which is not listed in OneTrust environment will be considered as invalid input.

Note: If the languageCode passed by your application is valid, but does not match with a language configuration for your template, then the SDK will return content in the default language configured in OneTrust environment (usually, but not always, English).
paramsDictionaryDictionary of parameters to override initialization settings. Parameters are optional, but you must have a non-null object defined, even if it is blank. See params section below for more information.
autoShowBannerBooleanAutomatically display the banner UI when download has completed successfully. This follows the shouldShowBanner() logic to ensure the user should be presented with a banner. autoShowBanner defaults to false.

If autoShowBanner is set to true and shouldShowBanner() logic returns true, the method for showBannerUI() will be called automatically and the user will see the Banner UI. You will not need to separately call showBannerUI() as this is taken care of by the autoShowBanner logic.

Params

All values below are optional.

KeyValueDescription
countryCodeISO country codeOverrides the geolocation of the user
regionCodeISO region codeOverrides the geolocation of the user, used in conjunction with countryCode
androidUXParamsJSON StringSets UI/UX overrides for Android (see Custom Styling section below)
profileSyncParamsDictionaryAllows for cross-device syncing of consent preferences. See Cross-Device Consent below.

Cross Device Consent

Cross-Device Consent is an optional feature. The parameters below are not required for initializing the SDK. Each of the parameters are required to sync the user's consent profile.

const syncParams = {
    identifier: '[email protected]',
    syncProfileAuth: 'eyJhbGci...',
  };

const startSDKParams = {profileSyncParams:syncParams}
KeyTypeDescription
identifierStringUser identifier
syncProfileAuthStringJWT auth token required to retrieve a user profile

Display User Interfaces

The OneTrust SDK manages several different user interfaces to display to a user. Here's a list below for your reference:

NameDescriptionMethod to Show
BannerNotice to the user of their privacy rights. Has configurable text and buttons for Accept All, Reject All, Manage Preferences, and Close Banner.

Note: Each of these buttons can be toggled On/Off in the Admin Console.
showBannerUI()
Preference CenterAn interface for the user to view their current profile settings and update their choices based on the configuration provided for them. Has configurable text and buttons for Accept All, Reject All, Save Settings, and Close Preference Center.

Note: You can choose to hide each button except Save Settings - this is required for a User to update their choices.
showPreferenceCenterUI()
Purpose DetailsThe Purpose Details (or Category Details) view shows granular detail about the category and also shows the SDK LIst link, Vendor List link, and child categories based on configuration.none, sub-view of Preference Center
SDK ListAn interface to show a granular list of SDKs to the user. This list may be filtered by Category to provide more transparency to the User.

Note: This can be hidden in Template Settings in the Admin Console.
none, sub-view of Preference Center
IAB Vendor ListAn interface, shown only for IAB2 type templates. Displays a list of 3rd party ad tech vendors under management by the application. This provides a way for users to opt in/out of consent for a particular vendor.none, sub-view of Preference Center
Vendor DetailsA child interface of Vendor List, this view shows more granular information about a vendor and its Purpose, Legitimate Interest, Special Feature, and Special Purpose settings.none, sub-view of Preference Center

The user interfaces without methods indicate they can only be navigated to based on user navigation and admin portal settings.

showBannerUI

This method will always show the Banner UI, regardless of the shouldShowBanner value.

OTPublishersNativeSDK.showBannerUI()

showPreferenceCenterUI

This method will always show the Preference Center UI.

OTPublishersNativeSDK.showPreferenceCenterUI()

shouldShowBanner

This method determines if a Banner UI should be displayed based on SDK determined logic.

OTPublishersNativeSDK.shouldShowBanner().then((result) =>
  console.log('Should the banner be shown? ', result),
);

How is shouldShowBanner() computed?

  1. Is the geolocation rule configured to show a banner? This is controlled by the showAlertNotice property in the JSON being true.

    • If showAlertNotice = false, the method returns false and a banner should not be shown for this region.
    • If showAlertNotice = true, move to the next check.
  2. Was the most recent SDK Publish configured to re-consent users? This is controlled by the presence of 2 values. 1) A LastReconsentDate property in JSON with non-null value. 2) A OneTrustLastReconsentDate value saved on disk

    • If the LastReconsentDate JSON is newer than the OneTrustLastReconsentDate on disk, the method returns true and a banner should be shown.
    • If no, move to the next check
  3. Is the geolocation rule configured for automatic re-consent AND did the user's automatic re-consent timer expire? This is controlled by measuring the difference between OneTrustLastConsentDate saved on disk and the Current Date and seeing if it is greater than or equal to OneTrustReconsentFrequencyDays in the JSON saved on disk. The SDK considers the date itself and not the time consent was given. For example, if the re-consent period is set to 1 day in my geolocation rule and the user provides consent at 11:59pm GMT, the banner will reappear at 12:00am GMT (1 minute later, but the next day).

    • If yes, the method returns true and a banner should be shown.
    • If no, move to the next check
  4. Is Cross Device Consent enabled and were 100% of Purposes synced? This is controlled by the profile.sync.allPurposesUpdatedAfterSync property in JSON being true.

    • If yes, the method returns false and a banner should not be shown. This is because each of the Categories/Purposes managed by the SDK were 100% synced from the user's profile on the OneTrust server.
    • If no, move to the next check.
  5. Is Cross Device Consent enabled and is the user being exposed to new Categories/Purposes since the last time their consent was saved? This would only occur if Cross Device Consent is enabled and there was a new publish to the SDK which exposes new Categories/Purposes that have at least 1 SDK assigned to it.

    • If yes, the method returns true and a banner should be shown.
    • If no, move to the next check.
  6. Has the user previously given consent and is that consent stored at disk?

    • If yes, the method returns false and a banner should not be shown.
    • If no, the method returns true and a banner should be shown because this is the first time they are being asked to give consent on the app.
  7. Has a new category been added post giving consent?

    • If yes, the method returns true and a banner should be shown again because user needs to give consent to the new category.
    • If no, the method returns false and a banner should not be shown.

When Consent Changes

When a user updates their consent choices or interacts with a OT SDK UI, the Application needs to become aware of that so it can control the next set of actions like:

  • Allowing or Restricting processing of 3rd party SDKs based on their categorization
  • Passing latest User consent values to 3rd Party SDKs
  • Passing the IAB’s encoded TC String to 3rd party SDKs
  • Passing the IAB’s USP String to 3rd Party SDKs
  • Routing the User to another location in the App
  • Displaying messages to the User of their changes
  • Logging updates to internally owned APIs
  • etc.

Consent Values

OneTrust universally uses the following values for consent status:

Consent valueDescription
1Consent given
0Consent not given
-1Consent not yet gathered, or SDK not initialized

Listening for Consent Changes

The OneTrust SDK broadcasts consent events when you call startSDK() and when consent values change. You can use these events and consent values to trigger some action. Your app can listen to either the categories itself or each individual SDK you want to manage. OneTrust recommends setting up observers on the category level to minimize the amount of observers you have to initialize.

Use Case: Applications needs observers for the SDKs or Categories that require some action to be taken when a user gives/withdraws their consent.

Example: When a user opts out of the "Sale of Personal Data" category, set a privacy or opt out flag in Targeting SDKs in scope so no personalized ads or ads of any kind are shown to the user.

On iOS, you must tell the bridge which consent categories and SDK IDs are eligible for broadcast. The code sample below shows an application allowing broadcasts for two categories (CXXXX) and an SDK ID (as a GUID).

OTPublishersNativeSDK.setBroadcastAllowedValues(['C0002','C0003', '4dfa896d-101e-4f0d-8620-a8546aaef187']);

The parameters passed are the events the iOS platform will be allowed to emit. This method has a conditional built in so that it will not execute on Android devices.

To start listening for consent changes, call the listenForConsentChanges method, which accepts a Category ID or an SDK ID as a string, and a callback function.

OTPublishersNativeSDK.listenForConsentChanges('C0002', (id, status) =>
  console.log('Consent status for ', id, ' has been updated to ', status),
);

The callback will be executed every time the consent status is updated.

OTConsentUpdated

The SDK will also broadcast a generic event every time a OneTrust UI (banner or preference center) is dismissed.

Use case: Applications need to know when they can query for latest consent for vendors, categories, SDKs, etc. This is useful in cases where you do not or cannot set up multiple observers for each category or SDK.

Event name: OTConsentUpdated

OTPublishersNativeSDK.listenForConsentChanges('OTConsentUpdated' =>
  console.log('Event triggered');
);

To stop listening for changes (for example, when your component is unmounted,) simply call:

OTPublishersNativeSDK.stopListeningForConsentChanges();

This will cancel all listeners.

Querying for Consent

Query the current consent status for any of the categories or SDKs included in your application. This can be used to determine what privacy action is needed at app launch or anytime the consent status is needed without being notified by an event broadcast. Simply pass in the Category ID (eg. C0001) or SDK ID and the method will return the current consent status (integer value).

OTPublishersNativeSDK.getConsentStatusForCategory('C0002').then((result) =>
  console.log('Consent Status for category C0002 = ' + result),
);
OTPublishersNativeSDK.getConsentStatusForSDKID('06a13b51-81a1-42a6-9121-80b4fc52d859').then((result) => 
  console.log('Consent Status for 06a13b51-81a1-42a6-9121-80b4fc52d859 = ' + result), 
);

Clear SDK Consents and Data

This method clears all data from the SDK:

OTPublishersNativeSDK.clearOTSDKData();

Special Configurations

Passing Consent to WebViews

If your application uses WebViews to present content and the pages rendered are running the OneTrust Cookies CMP, you can inject a JavaScript variable, provided by SDK, to pass consent from the native application to your WebView.

The JavaScript must be evaluated before the Cookies CMP loads in the webview. Therefore, it is recommended to evaluate the JavaScript early on in the WebView load cycle.

getOTConsentJSForWebView

var jsToPass = await OTPublishersNativeSDK.getOTConsentJSForWebView()  
//WebView JS Evaluation logic here

If your application is using react-native-webview, any injected JavaScript is wrapped in a self-invoking function, meaning that any variables set are not in the global scope. For the OneTrust Cookie Compliance module to pick up the required changes, the variable must be at a global scope. To accomplish this, a substring can be used to place the payload in the window scope:

var jsToPass = await OTPublishersNativeSDK.getOTConsentJSForWebview()  
jsToPass = `window.OTExternalConsent${jsToPass.substring(21)}`  
//WebView JS Evaluation logic here

Example output:

var OTExternalConsent = {
  "USPrivacy": "1---",
  "addtlString": "",
  "consentedDate": "Tue, 6 Apr 2021 16:13:41 +0100",
  "groups": "C0002:1,C0003:1,C0005:0,C0004:0,C0001:1",
  "tcString":"CPEPMp6PEPMp6AcABBFRBUCgAAAAAAAAAChQHrAA...",
  "gppString":"DBABzw~1YNY~BVQqAA...."
}

Important

It's recommended that the application call getOTConsentJSForWebview when you need to render a WebView. This ensures the payload is up to date based on the user's latest consent.

However, if you have a use case to call this method after consent has been changed by the user on the app, you can utilize the OTConsentUpdatedbroadcast from the SDK. This event is broadcast any time a OneTrust UI has been dismissed.

Do not rely on the broadcasts for category events. Due to some order of operations under the hood, the JS variable above may not be updated by the time you call getOTConsentJSForWebview.

You can view more information (including FAQs) in the native documentation here: iOS | Android

Programmatically Update Consent

When using the out of the box UI, the SDK will handle updates to the consent status. However, the app can programmatically update a consent value for a category (e.g. C0002, C0003, etc) if needed. Modifying the user's consent is a two step approach. updatePurposeConsent is used to set the state of the consent (toggles) on the UI and saveConsent is used to commit and save the consent to local storage. saveConsent MUST be called or consent will NOT be committed and changed.

To update the consent status of a category:

OTPublishersNativeSDK.updatePurposeConsent("C0002",false)
ParameterTypeDescription
Category IDStringID of the category to be updated
Consent valueBooleanConsent status given by the user for a category/group

To save and log the changes:

Be sure to import {OTConsentInteraction} from react-native-onetrust-cmp

var result = await OTPublishersNativeSDK.saveOTConsent(OTConsentInteraction.preferenceCenterConfirm);
Interaction TypesDescription
bannerAllowAllUser has accepted all on the banner.
bannerRejectAllUser has rejected all on the banner.
bannerContinueWithoutAcceptingUser has selected the "Continue Without Accepting" CTA on the banner.
bannerCloseUser has selected the 'x' on the banner.
preferenceCenterAllowAllUser has selected Allow All in the preference center.

Apple App Tracking Transparency

If enabled in your template, OneTrust can render a pre-prompt UI and then show the App Tracking Transparency prompt immediately after. You can view more information about this here.

To surface the pre-prompt, call the following method. Be sure to import {OTDevicePermission} from 'react-native-onetrust-cmp' first.

showConsentUI

OTPublishersNativeSDK.showConsentUI(OTDevicePermission.IDFA).then(()=>{
  console.log("ATT Prompt Complete")
})

To get the status of the user's ATT selection:

getATTStatus

var status = await OTPublishersNativeSDK.getATTStatus()
console.log(`ATT Status is ${status}`)

Status will return:

  • authorized
  • denied
  • notDetermined
  • restricted

This is consistent with Apple's definitions.

Google Consent Mode

Google Consent Mode allows web and app developers to adjust tag and app SDK behavior based on user consent choices. Google will be able to dynamically adapt the behavior of Google tags, Google Analytics, Google Ads, Floodlight and Conversion Linker. View more information in the native documentation here: iOS | Android

To retrieve Google Consent Mode consent statuses:

OTPublishersNativeSDK.getOTGoogleConsentModeData();

Sample response:

{
"analytics_storage": "GRANTED",
"ad_storage": "DENIED",
"ad_user_data": "DENIED",
"ad_personalization": "DENIED",
"functionality_storage": "GRANTED",
"personalization_storage": "GRANTED",
"security_storage": "DENIED"
}

Dark Mode

By default, the SDK will inherit the device's light mode and dark mode settings. This method allows you to programmatically override it. Change the boolean to true or false.

OTPublishersNativeSDK.shouldEnableDarkMode(true);

Customize User Interfaces

This section is optional as most UI configurations are primarily made through the OneTrust tenant. If your app has a use case where it needs make additional configurations (e.g. font family) otherwise not available in the tenant OR if it needs to control the UI configurations locally, you can use these custom configurations.

Android - Custom styling with uxParams JSON

OneTrust allows you to add custom styling to the UI by passing in a formatted JSON. Build out your JSON by following the guide in the OneTrust Developer Portal.

Simply pass in the JSON as a string as a parameter in the initialization.

const uxParamsJSON = JSON.stringify(require('./assets/AndroidUXParams.json'));

OTPublishersNativeSDK.startSDK(
  'cdn.cookielaw.org',
  '162cfe19-aff6-4d60-b10e-6e7b6fdcfb8b-test',
  'th',
  {androidUXParams: uxParamsJSON},
  true,
)

iOS - Custom Styling with UXParams Plist

Custom styling can be added to your iOS app by using a .plist file in the iOS platform code. In addition to adding the .plist file (which can be obtained from the OneTrust Demo Application) to your bundle, there are a few changes that need to be made in the platform code, outlined below. Review the guide in the OneTrust Developer Portal.

In appDelegate.h, import OTPublishersHeadlessSDK and make sure that AppDelegate conforms to the OTUIConfigurator protocol.

#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import <OTPublishersHeadlessSDK/OTPublishersHeadlessSDK.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, OTUIConfigurator>


@end

In appDelegate.m, set the UIConfigurator to self. Then conform to the shouldUseCustomUIConfig and customUIConfigFilePath protocol methods.


#import "AppDelegate.h"
#import "MainViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    [OTPublishersHeadlessSDK.shared setUiConfigurator:self]; //set UIConfigurator to Self
    ...
    return ...
}


- (BOOL)shouldUseCustomUIConfig { //conform to shouldUseCustomUIConfig
    return true;
}

- (NSString *)customUIConfigFilePath{ //conform to filepath protocol method
    NSString * configFile = [[NSBundle mainBundle] pathForResource:@"OTSDK-UIConfig-iOS" ofType:@"plist"]; //find path for config file
    return configFile;
}

@end

Retrieve Data Subject Identifier

The current active data subject identifier can retrieved programmatically by calling:

var id = await OTPublishersNativeSDK.getCurrentActiveProfile()

Customize SDK Log Levels

The OneTrust SDK supports the ability to customize log types printed to the console. You can control this log level by passing in your preferred minimum log level.

OTPublishersNativeSDK.enableOTSDKLog(OTLoggerConstant.noLogs);
Log LevelDescription
OTLoggerConstant.errorLogs only errors
OTLoggerConstant.warningLogs warnings and everything above
OTLoggerConstant.infoLogs info and everything above
OTLoggerConstant.debugLogs debug and everything above
OTLoggerConstant.verboseLogs verbose and everything above
OTLoggerConstant.noLogsTurns off all SDK logging

Universal Consent Purposes

📘

Important

Universal Consent Purposes for Mobile is part of the UCPM offering and you must have a UCPM license to use this module.

Universal Consent can be used to serve a different use case compared to the regular Mobile App Consent banner and this can also be configured within the Mobile SDK. Rather than collecting user consent to help manage SDKs and other technologies on the app, Universal Consent helps collect consent for purposes like promotional emails, newsletters, SMS messaging, etc. that typically require an integration with a third party system like Salesforce and Marketo. After a Universal Consent transaction is collected, integration workflows can be triggered within the OneTrust tool.

Universal Consent requires a user identifier to work properly. In order to set a data subject and keep their consent in sync with other collection methods, utilize the guidance for cross-device consent above.

Display Universal Consent Preference Center

To load the Universal Consent preference center over the current screen:

OTPublishersNativeSDK.showConsentPurposesUI()

Query for Consent Values

This plugin exposes async methods to retrieve the current state of the users' consent.

To query for purpose consent:

var consent = await OTPublishersNativeSDK.getUCPurposeConsent('purposeId')
ArgumentTypeDescription
purposeIdStringThe GUID of the purpose to retrieve.

Value returned:

StatusExplanation
1Consent is given
0Consent is not given
-1Consent not yet gathered, or SDK not initialized

To query for a custom preference nested under a purpose:

var consent = await OTPublishersNativeSDK.getUCCustomPreferenceConsent('customPreferenceOptionId',
 'customPreferenceId','purposeId')
ArgumentTypeDescription
customPreferenceOptionIdStringThe GUID of the custom preference option
customPreferenceIdStringThe GUID of the custom preference group
purposeIdStringThe GUID of the purpose under which the custom preference is nested.

Value returned:

StatusExplanation
1Consent is given
0Consent is not given
-1Consent not yet gathered, or SDK not initialized

To query for a topic nested under a purpose:

var consent = await OTPublishersNativeSDK.getUCTopicConsent('topicOptionId', 'purposeId')
ArgumentTypeDescription
topicOptionIdStringThe GUID of the topic option
purposeIdStringThe GUID of the purpose under which the custom preference is nested.

Value returned:

StatusExplanation
1Consent is given
0Consent is not given
-1Consent not yet gathered, or SDK not initialized

Programmatically Set Consent Values

The package exposes methods to programmatically set the users' consent values. A common use case is when a sign-up form has a checkbox at the bottom to allow the user to opt into emails. In this case, the application would set the value of the associated purpose, and the user could change his or her decision later in the preference center.

After making consent updates, the application must call the saveUCConsent() function to commit the changes.

To update the top-level purpose's consent:

var consent = await OTPublishersNativeSDK.updateUCPurposeConsent('purposeId', true)
ArgumentTypeDescription
purposeIdStringThe GUID of the purpose to update
consentBooleanWhether or not consent has been granted for the specified purpose

To update a custom preference nested under a purpose:

var consent = await OTPublishersNativeSDK.updateUCCustomPreferenceConsent('customPreferenceOptionId',
 'customPreferenceId','purposeId', true)
ArgumentTypeDescription
customPreferenceOptionIdStringThe GUID of the custom preference option
customPreferenceIdStringThe GUID of the custom preference group
purposeIdStringThe GUID of the purpose under which the custom preference is nested.
consentBooleanWhether or not consent has been granted for the specified item

To update a topic nested under a purpose:

var consent = await OTPublishersNativeSDK.updateUCTopicConsent('topicOptionId', 'purposeId', true)
ArgumentTypeDescription
topicOptionIdStringThe GUID of the topic option
purposeIdStringThe GUID of the purpose under which the custom preference is nested.
consentBooleanWhether or not consent has been granted for the specified item

Save Consent

After making updates to the consent values, the application must call the following method to commit the changes:

OTPublishersNativeSDK.saveUCConsent()