From 5ccc72cea166c40c91707fbcfcbe9795ad907a2f Mon Sep 17 00:00:00 2001 From: Alex Freas Date: Mon, 13 Apr 2026 12:14:54 +0100 Subject: [PATCH] Add react native integration guide to documentation --- documentation/README.md | 5 + ...-react-native-sdk-in-a-react-native-app.md | 703 ++++++++++++++++++ 2 files changed, 708 insertions(+) create mode 100644 documentation/integrating-the-react-native-sdk-in-a-react-native-app.md diff --git a/documentation/README.md b/documentation/README.md index 0fa05ed7..b79e3482 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -5,6 +5,7 @@ children: - ./integrating-the-node-sdk-in-a-node-app.md - ./integrating-the-web-sdk-in-a-web-app.md - ./integrating-the-react-web-sdk-in-a-react-app.md + - ./integrating-the-react-native-sdk-in-a-react-native-app.md --- # Guides @@ -25,3 +26,7 @@ are intended to be used. - [Integrating the Optimization React Web SDK in a React App](./integrating-the-react-web-sdk-in-a-react-app.md): step-by-step client-side integration guidance covering providers, consent, entry personalization, interaction tracking, live updates, router adapters, and preview panel setup +- [Integrating the Optimization React Native SDK in a React Native App](./integrating-the-react-native-sdk-in-a-react-native-app.md): + step-by-step React Native / Expo integration guidance covering OptimizationRoot setup, consent, + OptimizedEntry personalization and interaction tracking, live updates, screen tracking, and the + in-app preview panel — referenced against the Colorful-Team-Org demo diff --git a/documentation/integrating-the-react-native-sdk-in-a-react-native-app.md b/documentation/integrating-the-react-native-sdk-in-a-react-native-app.md new file mode 100644 index 00000000..ebd71df9 --- /dev/null +++ b/documentation/integrating-the-react-native-sdk-in-a-react-native-app.md @@ -0,0 +1,703 @@ +# Integrating the Optimization React Native SDK in a React Native App + +Use this guide when you want to add personalization, analytics, screen tracking, and a preview panel +to a React Native (or Expo) application using `@contentful/optimization-react-native`. + +The React Native SDK builds on the Optimization Core Library and adds React Native-specific +providers, hooks, and components — including AsyncStorage persistence, viewport-based view tracking, +tap tracking, screen tracking, navigation integration, and an in-app preview panel. + +## A Reference App You Can Compare Against + +The +`[Colorful-Team-Org/ReactNativeOptimizationDemo](https://github.com/Colorful-Team-Org/ReactNativeOptimizationDemo)` +repository contains two side-by-side Expo apps that implement the exact same UI from the same +Contentful space: + +| App | What it shows | +| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ContentfulDemoBase` | Plain Contentful Delivery API integration. Every user sees the same content. | +| `ContentfulDemoOptimized` | The same UI, converted to use `@contentful/optimization-react-native`. Adds personalization, view/tap tracking, screen tracking, and the preview panel FAB. | + +Diffing the two apps is the fastest way to see what an Optimization integration actually changes. +Throughout this guide, "demo" refers to `ContentfulDemoOptimized`, and file paths point to that +project (e.g. `ContentfulDemoOptimized/App.tsx`). + +The demo focuses on these conversion points: + +- `App.tsx` — wrapping the navigation tree in `OptimizationRoot` and + `OptimizationNavigationContainer`. +- `src/screens/HomeScreen.tsx` — wrapping a CTA entry in `` for personalization and + wrapping each blog post card for tap/view tracking. +- `src/screens/BlogPostDetailScreen.tsx` — wrapping a scrollable screen in + `` so viewport-based view tracking reflects scroll position. +- `src/contentfulClient.ts` — a normal Contentful Delivery API client; the Optimization SDK does not + replace it, it sits alongside it. + +## The Integration Flow + +Most React Native integrations follow this sequence: + +1. Install the SDK and its required peer dependencies. +2. Wrap the app in `OptimizationRoot` with the minimum config (`clientId`). +3. Decide how consent should behave (default-on for trusted contexts, or gated by a UI prompt). +4. Wrap each personalizable Contentful entry in ``. +5. Enable view and/or tap tracking for the entries you care about. +6. Wrap scrollable screens in `` so viewport tracking is accurate. +7. Add screen tracking (either automatically via `OptimizationNavigationContainer` or per-screen + with `useScreenTracking`). +8. Optionally enable the preview panel for development builds. + +Table of Contents + +- [A Reference App You Can Compare Against](#a-reference-app-you-can-compare-against) +- [The Integration Flow](#the-integration-flow) +- [1. Install And Initialize With Minimal Configuration](#1-install-and-initialize-with-minimal-configuration) + - [Install Peer Dependencies](#install-peer-dependencies) + - [The Minimum Setup](#the-minimum-setup) + - [Access The SDK Instance With Hooks](#access-the-sdk-instance-with-hooks) +- [2. Handle Consent](#2-handle-consent) + - [Defaulting Consent To `true](#defaulting-consent-to-true)` + - [Gating Consent On A Banner](#gating-consent-on-a-banner) + - [Reading And Reacting To Consent State](#reading-and-reacting-to-consent-state) + - [Revoking Consent](#revoking-consent) +- [3. Personalize Entries With OptimizedEntry](#3-personalize-entries-with-optimizedentry) + - [Fetch The Entry With `include: 10](#fetch-the-entry-with-include-10)` + - [Render The Variant With A Render Prop](#render-the-variant-with-a-render-prop) + - [Pass-Through For Non-Optimized Entries](#pass-through-for-non-optimized-entries) +- [4. Interaction Tracking With OptimizedEntry](#4-interaction-tracking-with-optimizedentry) + - [Global Defaults Via OptimizationRoot](#global-defaults-via-optimizationroot) + - [Per-Component Overrides](#per-component-overrides) + - [Custom Visibility And Time Thresholds](#custom-visibility-and-time-thresholds) + - [Use OptimizationScrollProvider For Scrollable Screens](#use-optimizationscrollprovider-for-scrollable-screens) +- [5. Enabling And Disabling Live Updates](#5-enabling-and-disabling-live-updates) + - [Default Behavior](#default-behavior) + - [Global Live Updates](#global-live-updates) + - [Per-Component Live Updates](#per-component-live-updates) + - [Resolution Priority](#resolution-priority) +- [6. Screen Tracking](#6-screen-tracking) + - [Automatic Tracking With OptimizationNavigationContainer](#automatic-tracking-with-optimizationnavigationcontainer) + - [Per-Screen Tracking With `useScreenTracking](#per-screen-tracking-with-usescreentracking)` + - [Dynamic Names With `useScreenTrackingCallback](#dynamic-names-with-usescreentrackingcallback)` +- [7. Preview Panel](#7-preview-panel) + - [Enabling The Preview Panel](#enabling-the-preview-panel) + - [Customizing The Floating Action Button](#customizing-the-floating-action-button) + - [Preview Panel And Live Updates](#preview-panel-and-live-updates) +- [Reference Implementations To Compare Against](#reference-implementations-to-compare-against) + +## 1. Install And Initialize With Minimal Configuration + +### Install Peer Dependencies + +```sh +pnpm add @contentful/optimization-react-native @react-native-async-storage/async-storage +``` + +For offline support (recommended), also install: + +```sh +pnpm add @react-native-community/netinfo +``` + +The SDK uses AsyncStorage to persist consent, profile, and selected optimizations across app +launches. `netinfo` is optional but lets the SDK queue events while the device is offline and flush +them automatically when connectivity returns. + +> [!NOTE] The Optimization SDK depends on native modules (e.g. `@react-native-clipboard/clipboard` +> for the preview panel). Expo apps using Optimization need a custom dev build (`expo run:ios` / +> `expo run:android`) — Expo Go is not enough. The demo's `[ContentfulDemoOptimized` README +> section](https://github.com/Colorful-Team-Org/ReactNativeOptimizationDemo#setup) walks through +> `expo prebuild` and the resulting native build. + +### The Minimum Setup + +Wrap your app's root in ``. This is the recommended entry point — it composes the +`OptimizationProvider`, `LiveUpdatesProvider`, and `InteractionTrackingProvider` for you and manages +the SDK instance lifecycle. + +```tsx +import { OptimizationRoot } from '@contentful/optimization-react-native' + +export default function App() { + return ( + + + + ) +} +``` + +That is the minimum viable setup. `clientId` is the only required prop; everything else falls back +to safe defaults (environment defaults to `'main'`, channel to `'mobile'`, etc.). + +The demo's +`[ContentfulDemoOptimized/App.tsx](https://github.com/Colorful-Team-Org/ReactNativeOptimizationDemo/blob/main/ContentfulDemoOptimized/App.tsx)` +shows a more typical setup that adds the navigation container, a defaults block, and the preview +panel: + +```tsx + + + {(navigationProps) => ( + + {/* ...stack/tab navigators... */} + + )} + + +``` + +Common props on `OptimizationRoot`: + +| Prop | Type | Required | Default | Description | +| ----------------------- | ---------------------------- | -------- | ------------------------------ | ----------------------------------------------------------------------- | +| `clientId` | `string` | Yes | N/A | Your Contentful Optimization client identifier | +| `environment` | `string` | No | `'main'` | Optimization environment to read from | +| `defaults` | `{ consent?: boolean, ... }` | No | `undefined` | Initial values applied at startup (e.g. `consent: true`) | +| `logLevel` | `LogLevels` | No | `'error'` | Minimum console log level | +| `previewPanel` | `PreviewPanelConfig` | No | `undefined` | Enables the in-app preview panel; see [Preview Panel](#7-preview-panel) | +| `liveUpdates` | `boolean` | No | `false` | Global live-updates default for `` | +| `trackEntryInteraction` | `{ views?, taps? }` | No | `{ views: true, taps: false }` | Default interaction tracking for `` | + +The full configuration reference (API endpoints, fetch retries, queue policy, event-builder +overrides) is documented in the +[React Native SDK README](../packages/react-native-sdk/README.md#configuration). + +### Access The SDK Instance With Hooks + +Inside the provider tree, use `useOptimization()` to interact with the SDK directly: + +```tsx +import { useOptimization } from '@contentful/optimization-react-native' + +function MyComponent() { + const optimization = useOptimization() + + const handlePress = async () => { + await optimization.identify('user-123', { plan: 'pro' }) + } + + return