Skip to content

Commit d6622eb

Browse files
add react-native-replay (#2178)
1 parent 1a7fade commit d6622eb

File tree

2 files changed

+337
-0
lines changed

2 files changed

+337
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
"react-native-replay": "Session Replay (React Native)",
3+
}
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
import { Callout } from "nextra/components";
2+
3+
# React Native Session Replay
4+
5+
Mixpanel's React Native Session Replay SDK enables you to capture and analyze user interactions in your mobile applications. Built as a Turbo Module for React Native's New Architecture, it provides native implementations for both iOS and Android with a unified JavaScript API.
6+
7+
## Features
8+
9+
- **📱 Cross-Platform Support** - Unified API for iOS and Android
10+
- **🎥 Session Recording** - Capture user interactions and screen recordings
11+
- **🔒 Privacy-First** - Built-in data masking for sensitive information
12+
- **⚡ High Performance** - Native implementation with minimal JavaScript bridge overhead
13+
- **🎯 Selective Recording** - Configurable sampling rates and recording controls
14+
- **🚀 New Architecture Ready** - Built as a Turbo Module with full type safety
15+
- **🛡️ Granular Privacy Controls** - Auto-masking and manual masking via wrapper components
16+
17+
## Requirements
18+
19+
- React Native >= 0.70
20+
- iOS >= 13.0
21+
- Android API Level >= 21
22+
- New Architecture support (backward compatible with old architecture)
23+
24+
## Installation
25+
26+
```sh
27+
npm install @mixpanel/react-native-session-replay
28+
```
29+
30+
or
31+
32+
```sh
33+
yarn add @mixpanel/react-native-session-replay
34+
```
35+
36+
### Platform Setup
37+
38+
#### iOS
39+
40+
The SDK dependencies are automatically added via CocoaPods. Your project must target iOS 13 or later.
41+
42+
```sh
43+
cd ios && pod install
44+
```
45+
46+
#### Android
47+
48+
Dependencies are automatically added through Gradle. Requirements:
49+
50+
- Minimum Android SDK 21+
51+
- Kotlin support enabled
52+
53+
## Quick Start
54+
55+
Here's a minimal example to get started with Session Replay:
56+
57+
```typescript
58+
import {
59+
MPSessionReplay,
60+
MPSessionReplayConfig,
61+
MPSessionReplayMask,
62+
} from "@mixpanel/react-native-session-replay";
63+
64+
// Initialize session replay
65+
const config = new MPSessionReplayConfig({
66+
wifiOnly: false,
67+
recordingSessionsPercent: 100,
68+
autoStartRecording: true,
69+
autoMaskedViews: [MPSessionReplayMask.Image, MPSessionReplayMask.Text],
70+
flushInterval: 5,
71+
enableLogging: true,
72+
});
73+
74+
await MPSessionReplay.initialize(token, distinctId, config).catch((error) => {
75+
console.error("Initialization error:", error);
76+
});
77+
78+
// Control recording
79+
await MPSessionReplay.startRecording();
80+
await MPSessionReplay.stopRecording();
81+
82+
// Check recording status
83+
const recording = await MPSessionReplay.isRecording();
84+
```
85+
86+
## Configuration
87+
88+
The `MPSessionReplayConfig` class provides comprehensive control over session replay behavior:
89+
90+
```typescript
91+
const config = new MPSessionReplayConfig({
92+
wifiOnly: boolean, // Default: true
93+
autoStartRecording: boolean, // Default: true
94+
recordingSessionsPercent: number, // Default: 100 (range: 0-100)
95+
autoMaskedViews: MPSessionReplayMask[], // Default: all types
96+
flushInterval: number, // Default: 10 (seconds)
97+
enableLogging: boolean, // Default: false
98+
});
99+
```
100+
101+
### Configuration Options
102+
103+
| Option | Type | Default | Description |
104+
| -------------------------- | --------------------- | --------- | ----------------------------------------------- |
105+
| `wifiOnly` | boolean | `true` | Only transmit recordings over WiFi |
106+
| `autoStartRecording` | boolean | `true` | Automatically start recording on initialization |
107+
| `recordingSessionsPercent` | number | `100` | Percentage of sessions to record (0-100) |
108+
| `autoMaskedViews` | MPSessionReplayMask[] | All types | View types to automatically mask |
109+
| `flushInterval` | number | `10` | Interval in seconds to flush recordings |
110+
| `enableLogging` | boolean | `false` | Enable debug logging |
111+
112+
### Auto-Masked View Types
113+
114+
The `MPSessionReplayMask` enum defines view types that can be automatically masked:
115+
116+
```typescript
117+
enum MPSessionReplayMask {
118+
Text = "text", // Text inputs and labels
119+
Web = "web", // WebView content
120+
Map = "map", // Map views (iOS only)
121+
Image = "image", // Image components
122+
}
123+
```
124+
125+
**Example - Custom Auto-Masking:**
126+
127+
```typescript
128+
import {
129+
MPSessionReplayConfig,
130+
MPSessionReplayMask,
131+
} from "mixpanel-react-native-session-replay";
132+
133+
// Only mask text inputs and images
134+
const config = new MPSessionReplayConfig({
135+
autoMaskedViews: [MPSessionReplayMask.Text, MPSessionReplayMask.Image],
136+
});
137+
```
138+
139+
## API Reference
140+
141+
### initialize
142+
143+
Initialize the Session Replay SDK with your configuration.
144+
145+
```typescript
146+
initialize(
147+
token: string,
148+
distinctId: string,
149+
config: MPSessionReplayConfig
150+
): Promise<void>
151+
```
152+
153+
**Parameters:**
154+
155+
- `token` (required) - Your Mixpanel project token
156+
- `distinctId` (required) - User identifier for the session
157+
- `config` (required) - Session replay configuration
158+
159+
**Validation:**
160+
161+
- Token must be a non-empty string
162+
- distinctId must be a non-empty string
163+
- recordingSessionsPercent must be between 0 and 100
164+
165+
**Example:**
166+
167+
```typescript
168+
const config = new MPSessionReplayConfig({
169+
autoStartRecording: true,
170+
enableLogging: __DEV__, // Enable logging in development
171+
});
172+
173+
try {
174+
await MPSessionReplay.initialize("YOUR_TOKEN", "user-123", config);
175+
console.log("Session Replay initialized");
176+
} catch (error) {
177+
console.error("Failed to initialize:", error);
178+
}
179+
```
180+
181+
### startRecording
182+
183+
Start recording user interactions.
184+
185+
```typescript
186+
startRecording(): Promise<void>
187+
```
188+
189+
**Example:**
190+
191+
```typescript
192+
await MPSessionReplay.startRecording();
193+
```
194+
195+
### stopRecording
196+
197+
Stop recording user interactions.
198+
199+
```typescript
200+
stopRecording(): Promise<void>
201+
```
202+
203+
**Example:**
204+
205+
```typescript
206+
await MPSessionReplay.stopRecording();
207+
```
208+
209+
### isRecording
210+
211+
Check if session recording is currently active.
212+
213+
```typescript
214+
isRecording(): Promise<boolean>
215+
```
216+
217+
**Returns:** Boolean indicating recording status
218+
219+
**Example:**
220+
221+
```typescript
222+
const recording = await MPSessionReplay.isRecording();
223+
if (recording) {
224+
console.log("Session is being recorded");
225+
}
226+
```
227+
228+
### identify
229+
230+
Update the user identifier for the current recording session.
231+
232+
```typescript
233+
identify(distinctId: string): Promise<void>
234+
```
235+
236+
**Parameters:**
237+
238+
- `distinctId` (required) - New user identifier
239+
240+
**Example:**
241+
242+
```typescript
243+
// Update user ID after authentication
244+
await MPSessionReplay.identify("authenticated-user-456");
245+
```
246+
247+
## Privacy & Data Masking
248+
249+
Session Replay provides two approaches to protect sensitive data: automatic masking and manual masking.
250+
251+
### Automatic Masking
252+
253+
Configure which view types are automatically masked during initialization:
254+
255+
```typescript
256+
const config = new MPSessionReplayConfig({
257+
autoMaskedViews: [
258+
MPSessionReplayMask.Text, // Masks all text inputs
259+
MPSessionReplayMask.Image, // Masks all images
260+
MPSessionReplayMask.Web, // Masks all WebViews
261+
MPSessionReplayMask.Map, // Masks map views (iOS only)
262+
],
263+
});
264+
```
265+
266+
**Default Behavior:** All view types are masked by default for maximum privacy.
267+
268+
### Manual Masking with MPSessionReplayView
269+
270+
Use the `MPSessionReplayView` wrapper component for granular control over what gets masked:
271+
272+
```typescript
273+
import { MPSessionReplayView } from 'mixpanel-react-native-session-replay';
274+
275+
// Mask sensitive content
276+
<MPSessionReplayView sensitive={true}>
277+
<TextInput
278+
value={password}
279+
onChangeText={setPassword}
280+
secureTextEntry
281+
/>
282+
<Text>Social Security Number: {ssn}</Text>
283+
</MPSessionReplayView>
284+
285+
// Explicitly mark content as safe (not masked)
286+
<MPSessionReplayView sensitive={false}>
287+
<Text>Public information that should always be visible</Text>
288+
</MPSessionReplayView>
289+
```
290+
291+
### Complete Masking Example
292+
293+
```typescript
294+
import React, { useState } from "react";
295+
import { View, TextInput, Image, Text } from "react-native";
296+
import { MPSessionReplayView } from "mixpanel-react-native-session-replay";
297+
import { WebView } from "react-native-webview";
298+
299+
function ProfileScreen() {
300+
const [email, setEmail] = useState("");
301+
const [password, setPassword] = useState("");
302+
303+
return (
304+
<View>
305+
{/* Public information - not masked */}
306+
<Text>Welcome to Your Profile</Text>
307+
308+
{/* Sensitive user data - masked */}
309+
<MPSessionReplayView sensitive={true}>
310+
<View>
311+
<Text>Email: {email}</Text>
312+
<TextInput
313+
value={email}
314+
onChangeText={setEmail}
315+
placeholder="[email protected]"
316+
/>
317+
318+
<Text>Password:</Text>
319+
<TextInput
320+
value={password}
321+
onChangeText={setPassword}
322+
secureTextEntry
323+
/>
324+
325+
<Image source={{ uri: profilePhotoUrl }} />
326+
</View>
327+
</MPSessionReplayView>
328+
329+
{/* WebView masked by default if Web type is in autoMaskedViews */}
330+
<WebView source={{ uri: "https://example.com/terms" }} />
331+
</View>
332+
);
333+
}
334+
```

0 commit comments

Comments
 (0)