@redacto.io/consent-sdk-react-native
v2.1.0
Published
React Native SDK for integrating Redacto consent notices and privacy center in mobile apps.
Readme
@redacto.io/consent-sdk-react-native
React Native SDK for Redacto's Consent Management Platform. Provides consent notice components and a full Privacy Center for end-user consent / DSR management on iOS and Android.
Entry Points
| Import path | What you get |
| -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| @redacto.io/consent-sdk-react-native | Consent notice components: RedactoNoticeConsent, RedactoNoticeConsentInline |
| @redacto.io/consent-sdk-react-native/privacy-center | Privacy Center: certified RedactoPrivacyCenter, composable components, UI primitives, headless API client and hooks |
The notice entry point depends only on react-native-svg. The Privacy Center entry point depends on the optional peers listed below.
Installation
pnpm add @redacto.io/consent-sdk-react-native react-native-svgNote:
react-native-svgmust be linked for native builds. Follow the react-native-svg setup guide.
Peer Dependencies
| Peer | Required for | Notes |
| -------------------------- | --------------------------- | ------------------------------------------------------ |
| react | All | ^18 \|\| ^19 |
| react-native | All | >=0.72 |
| react-native-svg | All | >=13 |
| expo-audio | Notice TTS playback | Optional. Required to enable text-to-speech audio |
| @tanstack/react-query | Privacy Center | Optional. Required for /privacy-center imports |
| i18next, react-i18next | Privacy Center | Optional. Required for /privacy-center imports |
| dayjs | Privacy Center | Optional. Required for /privacy-center imports |
If you only use the consent notice components, install just the SDK + react-native-svg. If you use the Privacy Center, install the optional peers as well:
pnpm add @tanstack/react-query i18next react-i18next dayjsTo enable TTS audio in the consent notice, install expo-audio:
pnpm add expo-audioBackend Server Setup
The SDK never talks to Redacto with your CMS API key directly — your backend acts as a token broker. Obtain your CMS-API-Key from the Redacto Dashboard, store it in your backend's environment, and expose two endpoints to your mobile app:
- Generate access token —
POST /public/organisations/{org_uuid}/workspaces/{workspace_uuid}/tokens/generate-access-token - Refresh access token —
POST /consent/public/organisations/{org_uuid}/workspaces/{workspace_uuid}/tokens/refresh-token
Both endpoints expect the X-CMS-API-Key header. Example (Express):
import express from "express";
import axios from "axios";
const app = express();
app.use(express.json());
const CMS_API_KEY = process.env.CMS_API_KEY;
app.post("/api/consent/token", async (req, res) => {
const { email } = req.body;
const { organisation_uuid, workspace_uuid, base_url } = req.query;
const response = await axios.post(
`${base_url}/public/organisations/${organisation_uuid}/workspaces/${workspace_uuid}/tokens/generate-access-token`,
{ email },
{ headers: { "X-CMS-API-Key": CMS_API_KEY } }
);
res.json(response.data.detail); // { token, refresh_token, expires_at }
});
app.post("/api/consent/refresh-token", async (req, res) => {
const { refresh_token, organisation_uuid, workspace_uuid, base_url } = req.body;
const response = await axios.post(
`${base_url}/consent/public/organisations/${organisation_uuid}/workspaces/${workspace_uuid}/tokens/refresh-token`,
{ refresh_token },
{ headers: { "X-CMS-API-Key": CMS_API_KEY } }
);
res.json(response.data.detail);
});Never bundle CMS_API_KEY into the mobile app. In Expo apps, only non-sensitive values (UUIDs, URLs) belong in EXPO_PUBLIC_*.
Consent Notice Components
RedactoNoticeConsent
Modal consent component. Supports initial consent, reconsent, age verification, guardian form, and TTS playback.
import { RedactoNoticeConsent } from "@redacto.io/consent-sdk-react-native";
<RedactoNoticeConsent
noticeId="your-notice-uuid"
accessToken={accessToken}
refreshToken={refreshToken}
onAccept={() => navigation.navigate("Dashboard")}
onDecline={() => console.log("declined")}
/>;Props
| Prop | Type | Required | Description |
| --------------------------- | ----------------------------- | -------- | -------------------------------------------------------- |
| noticeId | string | ✓ | UUID of the consent notice |
| accessToken | string | ✓ | JWT access token |
| refreshToken | string | ✓ | JWT refresh token |
| baseUrl | string | | Override API base URL |
| settings | Partial<Settings> | | UI customisation (colours, border radius, fonts) |
| language | string | | Initial language code (e.g. "en") |
| blockUI | boolean | | Block the modal from being dismissed |
| applicationId | string | | Application-specific UUID |
| validateAgainst | "all" \| "required" | | Validation mode |
| includeFullyConsentedData | boolean | | Include already-consented items (review mode) |
| reviewModeButtonText | string | | CTA text in review mode |
| onAccept | () => void | ✓ | Called on successful consent |
| onDecline | () => void | ✓ | Called when user declines |
| onError | (error: Error) => void | | Called on API errors |
RedactoNoticeConsentInline
Inline consent component. Auto-submits when all required elements are checked and an access token is available.
import { RedactoNoticeConsentInline } from "@redacto.io/consent-sdk-react-native";
<RedactoNoticeConsentInline
org_uuid="org-uuid"
workspace_uuid="workspace-uuid"
notice_uuid="notice-uuid"
accessToken={accessToken}
onAccept={() => console.log("accepted")}
onValidationChange={(isValid) => setCanProceed(isValid)}
/>;Props
| Prop | Type | Required | Description |
| -------------------- | ---------------------------- | -------- | ------------------------------------------------- |
| org_uuid | string | ✓ | Organisation UUID |
| workspace_uuid | string | ✓ | Workspace UUID |
| notice_uuid | string | ✓ | Notice UUID |
| accessToken | string | | JWT access token (triggers auto-submit when set) |
| baseUrl | string | | Override API base URL |
| language | string | | Language code |
| settings | Partial<Settings> | | UI customisation |
| applicationId | string | | Application-specific UUID |
| onAccept | () => void | | Called on successful consent |
| onDecline | () => void | | Called when user declines |
| onError | (error: Error) => void | | Called on errors |
| onValidationChange | (isValid: boolean) => void | | Fires when validation state changes |
TTS Audio
If expo-audio is installed, the consent notice will dynamically load it and enable text-to-speech playback. The SDK calls setAudioModeAsync and creates an audio player internally — you don't need to set anything up beyond installing the package. See the expo-audio docs if you need to customise audio session behaviour app-wide.
If expo-audio is not installed, the notice still renders and functions; only the TTS button is disabled.
Privacy Center
The Privacy Center is a separate entry point (@redacto.io/consent-sdk-react-native/privacy-center) for letting end-users review and manage the consent they've given, see request activity, and file Data Subject Rights (DSR) cases — including in-app messaging on existing cases. It ships as a certified screen, composable components, UI primitives, and a headless core.
Certified UI
RedactoPrivacyCenter renders the full Privacy Center experience with built-in navigation, auth, theming, and i18n.
import { RedactoPrivacyCenter } from "@redacto.io/consent-sdk-react-native/privacy-center";
<RedactoPrivacyCenter
baseUrl={BASE_URL}
slug="acme-co"
accessToken={accessToken}
refreshToken={refreshToken}
theme="light"
initialPage="consent-manager"
onError={(error) => {
console.error(error);
return false;
}}
/>;Props
| Prop | Type | Required | Default | Description |
| -------------- | ----------------------------------------------------------------------------- | -------- | -------------------- | ---------------------------------------- |
| baseUrl | string | ✓ | - | Consent server base URL |
| slug | string | ✓ | - | Workspace slug |
| accessToken | string | ✓ | - | JWT access token |
| refreshToken | string | ✓ | - | JWT refresh token |
| onError | (error: Error) => boolean | ✓ | - | Error handler; return true if handled |
| theme | "light" \| "dark" | | "light" | Theme variant |
| initialPage | "consent-manager" \| "form" \| "activity" \| "case-details" | | "consent-manager" | Page to render first |
| onBack | "back" \| "signout" | | - | Navbar back / signout control behaviour |
Composable Components
If you want to compose your own shell, import the screen-level building blocks instead of the certified component:
| Export | Purpose |
| ------------------ | ------------------------------------------------------ |
| ConsentManager | "Manage Consents" view |
| Form, FormPage | DSR / grievance form (component + full page wrapper) |
| ActivitiesList | List of past requests |
| CaseHistory | Per-product / per-purpose case history group |
| CaseDetailsPage | Case detail with messaging and document upload |
| Navbar | Top navigation bar |
| SideMenu | Drawer / side menu |
| BottomTabBar | Bottom tab navigation |
| Footer | Footer block |
These rely on the context providers (AuthProvider, BaseUrlProvider, NavigationProvider, ThemeProvider) — wrap them yourself if you compose the pages directly.
UI Primitives
For building custom screens that match Privacy Center styling, the package exports themed primitives: PCButton, PCInput, PCSelect, PCModal, PCCheckbox, PCLoader, PCEmpty, PCBadge.
Headless Core
For consumers who want fully custom UI, the headless core exposes the API client, orchestration helpers, hooks, and auth utilities:
- API client:
createConsentClient - Orchestration helpers (handle auth retry / token refresh internally):
getFormData,createCaseRequest,fetchProducts,fetchUserConsents,manageConsent,fetchActivities,fetchCaseHistory,getCaseMessages,sendCaseMessage,uploadCaseDocument,submitDocumentForRequest,createOtp,verifyOtp,exchangeToken - Auth utilities:
decodeJwtToken,isJwtExpired,ensureValidToken,signOutPrivacyCenter,compareEmails,getActivityTypeStatus,formatActivityType - React Query hooks:
useCaseHistory,useCaseMessages - Context providers:
AuthProvider+useAuth,BaseUrlProvider+useBaseUrl,NavigationProvider+useInternalNavigation,ThemeProvider+useTheme - Types:
Workspace,OrganizationDetail,DataElement,Purpose,UserConsent,Activity,CaseHistoryDetail,CaseMessage,MessageDocument,RequestTypeEnum,GrievanceTypeEnum,ConsentStatusEnum, and more (seeprivacy-center.tsfor the full export list)
Configuration and Env Best Practices
- The SDK is runtime-configured via props and does not read from
.envdirectly. - Keep API keys and server secrets on your backend only.
- In Expo apps, values read from
EXPO_PUBLIC_*are bundled into the app and should only contain non-sensitive config like UUIDs and URLs. - If you do not pass
baseUrl, the SDK defaults tohttps://api.redacto.io/consentfor both notice and Privacy Center surfaces.
License
Apache-2.0
