Show web pages with the app's consent in React Native
The Janus React Native SDK's useJanusWebView hook shows a web page that runs FidesJS with the consent the user gave in the app, in a react-native-webview WebView. The page starts from the app's consent, follows every later change without reloading, and reports its FidesJS events back to the app. Without the hook, the page's FidesJS knows nothing about the app: it shows its own banner, records a separate choice under a separate device ID, and its ad tags send a consent signal that doesn't match the app's.
This guide walks through showing a page through the hook, and giving the app's native ad SDKs and the page's ad tags the same consent.
How it works
When a page is shown through useJanusWebView:
- The hook seeds the page. Before the page's own scripts run, the hook writes the app's consent, fides string and
fides_user_device_idinto the page'sfides_consentcookie, at the domain FidesJS saves to. FidesJS starts from that cookie, so the page shows no banner and reports consent under the app's device ID. When the user hasn't given consent in the app yet, the hook deletes the page's cookie instead, and the page shows its banner as on a first visit. - The hook keeps the page in step with the app. When consent changes through the SDK, such as a choice in the experience,
setConsentorclearConsent, the hook sends it into every page it has mounted, without a reload. When the app's consent is cleared, the hook deletes the page's cookie and reloads the page, which then starts with no consent. - The page reports its events to the app. The page's FidesJS events reach
Janus.addConsentEventListeneraswebviewFides*events. - The page doesn't record consent itself. By default the hook stops the page's FidesJS from saving consent and recording notices served, so the app stays the one place consent is recorded.
- Sync goes one way, from the app to the page. A choice made in the page's own banner, which shows when the app has no consent yet, never reaches the app, and with
disablePageSaveson, the default, it isn't saved to Astralis either.
The seed and the bridge only run on the page's site, its registrable domain, such as example.com for www.example.com. A link to another site gets neither. Janus bridge messages from frames on other sites, such as an ad's iframe, are ignored. The page's own messages reach your onMessage from any frame, an ad's iframe included, so check event.nativeEvent.url, the URL of the frame that sent the message, before acting on one.
Step 1: Add react-native-webview to your app
useJanusWebView returns props for a react-native-webview WebView. The package is an optional peer dependency of the Janus React Native SDK, so add it to your app if you don't have it:
npm install react-native-webviewThe hook needs react-native-webview 14 or later, which reports the frame that sent each message. It adds native code, so rebuild the app afterwards.
Step 2: Load fides.js on the page
The page needs FidesJS from the same Privacy Center and property the app uses, so the page and the app share an experience:
- Load
fides.jsin<head>, before any ad tag. Ad tags read consent through__tcfapiand__gppwhen they start, so FidesJS has to be on the page first. - Add
gpp=truewhere the US Global Privacy Platform (GPP) applies. This bundles the GPP API, as described in the FidesJS GPP API reference. - Don't set
fides_overrides.fides_stringon the page. The hook seeds the fides string through the cookie. An override leaves the page's GPP signal not ready, and Google Publisher Tag then sends no ad request. - Host the page on your own domain. Serve it from your site's registrable domain, such as
www.example.com, rather than a shared hosting domain such asgithub.io. - Don't set
fides_cookie_suffix. The hook seeds thefides_consentcookie, so a page that reads a suffixed cookie ignores the seed and shows its own banner. - Set page overrides on
window.fides_overrides, not throughcustomOptionsPath. With a custom path, FidesJS reads another object and never sees the settings the hook adds to stop the page's own saves.
A page that doesn't load FidesJS has no consent management platform for its ad tags to ask, so those tags get no consent signal from the app. Show ad tags only on pages that load FidesJS.
<head>
<script src="https://privacy.example.com/fides.js?gpp=true"></script>
<!-- Ad tags go after fides.js -->
</head>Step 3: Render the page through useJanusWebView
- Call the hook with the page's URL. It returns
webViewProps, the props for theWebView, andready, which turns true once the app's consent has been read into the page's seed. - Mount the
WebViewonly oncereadyis true. The seed runs when the page starts, so aWebViewmounted earlier loads the page without it. - Spread
webViewPropson theWebView. Add any otherWebViewprops you need, but don't override the ones the hook returns.
import { WebView } from "react-native-webview";
import { useJanusWebView } from "@ethyca/janus-sdk-react-native";
export function ArticleScreen() {
const { webViewProps, ready } = useJanusWebView({
url: "https://www.example.com/article",
});
// The seed has to be in place before the page starts loading.
if (!ready) {
return null;
}
return <WebView {...webViewProps} style={{ flex: 1 }} />;
}webViewProps holds ref, source, injectedJavaScriptBeforeContentLoaded and onMessage. To receive the page's own postMessage messages, pass your handler to the hook's onMessage option rather than to the WebView. To reach the WebView instance, use webViewProps.ref.
Use your own native web view
If your app renders pages through its own native WebView subclass, for example to register it with an ad SDK, pass the subclass with react-native-webview's nativeConfig prop next to the hook's props. The seed, the bridge and consent updates work the same in the subclass.
<WebView
{...webViewProps}
nativeConfig={{ component: MyAdsWebView }}
style={{ flex: 1 }}
/>Step 4: Verify the page uses the app's consent
- Give consent in the app's privacy experience.
- Open the screen that shows the page. The page shows no banner, and its consent matches the app's.
- Listen with
Janus.addConsentEventListener. The listener receiveswebviewFidesInitializedfrom the page. - Change consent in the app while the page is open. The page applies the change without reloading.
Give ad SDKs the app's consent
Native ad SDKs
Native ad SDKs, such as Google Mobile Ads, read consent from the Interactive Advertising Bureau (IAB) keys on the device: UserDefaults on iOS and the default SharedPreferences on Android. Janus writes the keys of the IAB Transparency and Consent Framework (TCF), IABTCF_TCString and the related IABTCF_ keys, when the user makes a choice in a TCF experience. Start your ad SDKs once consent is in place:
import { Janus, JanusEventType } from "@ethyca/janus-sdk-react-native";
let adsStarted = false;
function startAds() {
if (!adsStarted) {
adsStarted = true;
// Start your ad SDKs here.
}
}
// Start ads once the user makes a choice in the experience.
const subscription = Janus.addConsentEventListener((event) => {
if (event.eventType === JanusEventType.experienceSelectionUpdated) {
startAds();
}
});
await Janus.initialize({ apiHost, propertyId });
if (!(await Janus.shouldShowExperience)) {
// No consent is needed now, so start ads with whatever keys are stored.
startAds();
}The experienceSelectionUpdated event carries the new consent and fidesString in its detail, so the listener can also act on the choice itself, for example by turning off personalized ads.
Ad SDKs that don't read the IAB keys
Some ad and analytics SDKs take consent through their own API instead of the IAB keys. Pass them the user's choice from Janus.consent when they start, and again from the consent in each experienceSelectionUpdated event's detail, using the notice keys your experience defines.
Ad tags in a web view
Ad tags inside a web view, such as Google Publisher Tag, read consent from the page's FidesJS, not from the device's IAB keys. Registering the web view with Google Mobile Ads (its WebView API for Ads) adds Google's own app signals to its ad requests, but carries no consent that the page's ad tags can read. Keep registering if you use it, and show pages that carry ad tags through useJanusWebView as well, so their FidesJS starts from the app's consent and their ad requests carry it. To do both, use your own native web view.
Hook reference
Options
| Option | Default | Effect |
|---|---|---|
url | Required | The page to load. The hook seeds this page's site. |
disablePageSaves | true | Stops the page's FidesJS from saving consent and recording notices served, so the app stays the one place consent is recorded. |
onMessage | None | Receives the page's own messages. The hook handles the Janus bridge's messages itself. |
ready turns false when url changes, so the Step 3 example unmounts the WebView until the new page's seed is ready. If you keep the WebView mounted instead, it stays on the current page until the new seed is ready, then loads the new page with it.
Events
The hook reports the page's FidesJS events to Janus.addConsentEventListener under these event types. Updates the hook itself sends into the page aren't reported back.
| Event type | FidesJS event |
|---|---|
webviewFidesInitializing | FidesInitializing |
webviewFidesInitialized | FidesInitialized |
webviewFidesUIShown | FidesUIShown |
webviewFidesUIChanged | FidesUIChanged |
webviewFidesModalClosed | FidesModalClosed |
webviewFidesUpdating | FidesUpdating |
webviewFidesUpdated | FidesUpdated |