diff --git a/content/en/product_analytics/session_replay/mobile/privacy_options.md b/content/en/product_analytics/session_replay/mobile/privacy_options.md deleted file mode 100644 index a97e7e591e5..00000000000 --- a/content/en/product_analytics/session_replay/mobile/privacy_options.md +++ /dev/null @@ -1,3091 +0,0 @@ ---- -title: Mobile Session Replay Privacy Options -description: Configure privacy options for Mobile Session Replay. -further_reading: - - link: /real_user_monitoring/session_replay/mobile - tag: Documentation - text: Mobile Session Replay - - link: /real_user_monitoring/session_replay/mobile/app_performance - tag: Documentation - text: How Mobile Session Replay Impacts App Performance - - link: /real_user_monitoring/session_replay/mobile/setup_and_configuration - tag: Documentation - text: Setup and Configure Mobile Session Replay - - link: /real_user_monitoring/session_replay/mobile/troubleshooting - tag: Documentation - text: Troubleshoot Mobile Session Replay - - link: /real_user_monitoring/session_replay - tag: Documentation - text: Session Replay ---- -

SDK

SDK


-

Overview

-

- Session Replay provides privacy controls to ensure organizations of any - scale do not expose sensitive or personal data. Data is stored on - Datadog-managed cloud instances and encrypted at rest. -

-

- Default privacy options for Session Replay protect end user privacy and - prevent sensitive organizational information from being collected. -

-

- By enabling Mobile Session Replay, you can automatically mask sensitive - elements from being recorded through the RUM Mobile SDK. When data is - masked, that data is not collected in its original form by Datadog's SDKs - and thus is not sent to the backend. -

-

Fine-grained masking

-

- Using the masking modes below, you can override the default setup on a - per-application basis. Masking is fine-grained, which means you can override - masking for text and inputs, images, and touches individually to create a - custom configuration that suits your needs. -

-

Text and input masking

-

- By default, the mask_all setting is enabled for all data. With - this setting enabled, all text and input content on screen is masked, as - shown below. -

-
-
- What your application screen may resemble when `mask` is enabled. -
-

Mask sensitive inputs

-

- With the mask_sensitive_inputs setting enabled, all text and - inputs are shown except those considered sensitive (passwords, emails, and - phone numbers). -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setTextAndInputPrivacy(TextAndInputPrivacy.MASK_SENSITIVE_INPUTS)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: .maskSensitiveInputs,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TextAndInputPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_SENSITIVE_INPUTS,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskSensitiveInputs,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Mask all inputs

-

- With the mask_all_inputs setting enabled, all inputs fields are - masked in the replay. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-.setTextAndInputPrivacy(TextAndInputPrivacy.MASK_ALL_INPUTS)
-.build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: .maskAllInputs,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TextAndInputPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_ALL_INPUTS,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskAllInputs,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Mask all

-

- With the mask_all setting enabled, all text and input fields - are masked in the replay. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setTextAndInputPrivacy(TextAndInputPrivacy.MASK_ALL)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: .maskAll,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TextAndInputPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_ALL,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskAll,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Image masking

-

- By default, the mask_all setting is enabled for all images. - With this setting enabled, all images on screen are masked. -

-
-

- For performance reasons, large images (those exceeding 1000x1000 total - pixels) are masked in Flutter, and will display "Large Image" in - the Session Replay player. -

-
-

Mask all images

-

- With the mask_all setting enabled, all images are replaced by - placeholders labeled 'Image' in the replay. -

-
-
- What your application screen may resemble when `mask-all` is enabled. -
-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setImagePrivacy(ImagePrivacy.MASK_ALL)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: .maskAll,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  ImagePrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  imagePrivacyLevel: ImagePrivacyLevel.MASK_ALL,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        imagePrivacyLevel: ImagePrivacyLevel.maskAll,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Mask content images

-

- You can manage content masking while still allowing system or bundled images - to be visible. -

-
-

- Use the maskNonBundledOnly setting to replace non-bundled - images with a "Content Image" placeholder in the replay. -

-
    -
  • - In UIKit, the SDK can determine whether an image is bundled and can mask - it accordingly. -
  • -
  • - In SwiftUI, this determination isn't possible. Instead, the SDK uses a - heuristic: if an image exceeds 100×100 points, it is assumed to be - non-bundled and is masked. -
  • -
-
-
-

- Select the mask_large_only setting, which replaces images - with dimensions that exceed 100x100dp with a "Content Image" - placeholder. -

-

- Note: These dimensions refer to the drawable resource, - not the view's size. -

-
-
-
-
- What your application screen may resemble when `mask_large_only` is enabled on Android. -
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setImagePrivacy(ImagePrivacy.MASK_LARGE_ONLY)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
- What your application screen may resemble when `mask_non_bundled_only` is enabled on iOS. -
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: .maskNonBundledOnly,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  ImagePrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  imagePrivacyLevel: ImagePrivacyLevel.MASK_NON_BUNDLED_ONLY,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-

- Bundled images are those that use AssetImage as their image - provider. -

-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        imagePrivacyLevel: ImagePrivacyLevel.maskNonAssetsOnly,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Show all images

-

- With the mask_none setting enabled, all images are shown in the - replay. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setImagePrivacy(ImagePrivacy.MASK_NONE)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: .maskNone,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  ImagePrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  imagePrivacyLevel: ImagePrivacyLevel.MASK_NONE,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-

Touch masking

-

- By default, the hide setting is enabled for all touches. With - this setting enabled, all touches on screen are hidden. -

-

Hide all touches

-

- With the hide setting enabled, all touches that occur during - the replay are hidden. This is the default setting. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setTouchPrivacy(TouchPrivacy.HIDE)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: .hide
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TouchPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  touchPrivacyLevel: TouchPrivacyLevel.HIDE,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        imagePrivacyLevel: ImagePrivacyLevel.maskNone,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Show all touches

-

- With the show setting enabled, all touches that occur during - the replay are shown. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setTouchPrivacy(TouchPrivacy.SHOW)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: .show
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TouchPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  touchPrivacyLevel: TouchPrivacyLevel.SHOW,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-

- Bundled images are those that use AssetImage as their image - provider. -

-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        touchPrivacyLevel: TouchPrivacyLevel.show,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Privacy overrides

-

- The sections above describe the global masking levels that apply to the - entire application. However, it is also possible to override these settings - at the view level. The same privacy levels as above are available for text - and inputs, images, touches, and an additional setting to completely hide a - specific view. -

-

- To ensure overrides are recognized properly, they should be applied as early - as possible in the view lifecycle. This prevents scenarios where Session - Replay might process a view before applying the overrides. -

-

- Privacy overrides affect views and their descendants. This means that even - if an override is applied to a view where it might have no immediate effect - (for example, applying an image override to a text input), the override - still applies to all child views. -

-

- Overrides operate using a "nearest parent" principle: if a view - has an override, it uses that setting. Otherwise, it inherits the privacy - level from the closest parent in the hierarchy with an override. If no - parent has an override, the view defaults to the application's general - masking level. -

-
-

Text and input override

-
-

- To override text and input privacy in Android classic view, use - setSessionReplayTextAndInputPrivacy on a view instance and - pass a value from the TextAndInputPrivacy enum. Passing - null removes the override. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a text and input override on your view
-myView.setSessionReplayTextAndInputPrivacy(TextAndInputPrivacy.MASK_SENSITIVE_INPUTS)
-// Remove a text and input override from your view
-myView.setSessionReplayTextAndInputPrivacy(null)
-
-
-
-
-

- To override text and input privacy in Jetpack Compose, use - Modifier.sessionReplayTextAndInputPrivacy on the modifier - of a composable and pass a value from the - TextAndInputPrivacy enum. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a text and input override on your view
-Text(modifier = Modifier
-    .padding(16.dp)
-    .sessionReplayTextAndInputPrivacy(textAndInputPrivacy = TextAndInputPrivacy.MASK_SENSITIVE_INPUTS),
-  text = "Datadog"
-)
-
-
-
-
-
-
-

- To override text and input privacy in UIKit views, use - dd.sessionReplayOverrides.textAndInputPrivacy on a view - instance and set a value from the - TextAndInputPrivacyLevel enum. Setting it to - nil removes the override. -

-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
// Set a text and input override on your view
-myView.dd.sessionReplayOverrides.textAndInputPrivacy = .maskSensitiveInputs
-// Remove a text and input override from your view
-myView.dd.sessionReplayOverrides.textAndInputPrivacy = nil
-
-
-
-
-

- To override text and input privacy in SwiftUI, wrap your content with - SessionReplayPrivacyView and configure the - textAndInputPrivacy parameter. You can combine this with - other privacy settings in the same view for better performance. -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct ContentView: View {
-    @State private var username = ""
-    @State private var password = ""
-
-    var body: some View {
-        // Set a text and input override on your SwiftUI content
-        SessionReplayPrivacyView(textAndInputPrivacy: .maskAllInputs) {
-            VStack {
-                Text("User Profile")
-                TextField("Enter name", text: $username)
-                SecureField("Password", text: $password)
-            }
-        }
-    }
-}
-
-
-
-
-
-
-

- To override text and input privacy in Flutter, use the - SessionReplayPrivacy widget to override the privacy - settings for an entire widget tree. Setting any value to - null keeps the privacy values unchanged from values - provided higher up the widget tree. -

-
-
-
-
-
-
-
-
-
- -
-
-
class MyWidget: StatelessWidget {
-  Widget build() {
-    return SessionReplayPrivacy(
-      textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskAllInputs,
-      child: TextField(
-        decoration: InputDecoration(
-          labelText: 'Simple Text Field',
-        ),
-      ),
-    );
-  }
-}
-
-
-
-
-
-

Image override

-
-

- To override image privacy in Android classic view, use - setSessionReplayImagePrivacy on a view instance and pass a - value from the ImagePrivacy enum. Passing - null removes the override. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set an image override on your view
-myView.setSessionReplayImagePrivacy(ImagePrivacy.MASK_ALL)
-// Remove an image override from your view
-myView.setSessionReplayImagePrivacy(null)
-
-
-
-
-

- To override image privacy in Jetpack Compose, use - Modifier.sessionReplayImagePrivacy on the modifier of a - composable and pass a value from the ImagePrivacy enum. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a image privacy override on your image
-Image(modifier = Modifier
-  .padding(16.dp)
-  .sessionReplayImagePrivacy(imagePrivacy = ImagePrivacy.MASK_ALL),
-  painter = painterResource(id = R.drawable.ic_datadog),
-  contentDescription = null
-)
-
-
-
-
-
-
-

- To override image privacy in UIKit views, use - dd.sessionReplayOverrides.imagePrivacy on a view instance - and set a value from the ImagePrivacyLevel enum. Setting it - to nil removes the override. -

-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
// Set an image override on your view
-myView.dd.sessionReplayOverrides.imagePrivacy = .maskAll
-// Remove an image override from your view
-myView.dd.sessionReplayOverrides.imagePrivacy = nil
-
-
-
-
-

- To override image privacy in SwiftUI, wrap your content with - SessionReplayPrivacyView and configure the - imagePrivacy parameter. -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct ProfileView: View {
-    let profileImageURL = URL(string: "https://example.com/profile.jpg")
-
-    var body: some View {
-        // Set an image privacy override on your SwiftUI content
-        SessionReplayPrivacyView(imagePrivacy: .maskAll) {
-            VStack {
-                Image("userAvatar")
-                    .resizable()
-                    .frame(width: 60, height: 60)
-                    .clipShape(Circle())
-
-                AsyncImage(url: profileImageURL) { image in
-                    image.resizable()
-                } placeholder: {
-                    ProgressView()
-                }
-                .frame(width: 100, height: 100)
-            }
-        }
-    }
-}
-
-
-
-
-
-
-

- To override image privacy in Flutter, use the - SessionReplayPrivacy widget to override the privacy - settings for an entire widget tree. Setting any value to - null keeps the privacy values unchanged from values - provided higher up the widget tree. -

-
-
-
-
-
-
-
-
-
- -
-
-
class MyWidget: StatelessWidget {
-  Widget build() {
-    return SessionReplayPrivacy(
-      imagePrivacyLevel: ImagePrivacyLevel.maskAll,
-      child: Image.asset('assets/my_image.png'),
-    );
-  }
-}
-
-
-
-
-
-

Touch override

-
-

- To override touch privacy in Android classic view, use - setSessionReplayTouchPrivacy on a view instance and pass a - value from the TouchPrivacy enum. Passing - null removes the override. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a touch override on your view
-view.setSessionReplayTouchPrivacy(TouchPrivacy.HIDE)
-// Remove a touch override from your view
-view.setSessionReplayTouchPrivacy(null)
-
-
-
-
-

- To override touch privacy in Jetpack Compose, use - Modifier.sessionReplayTouchPrivacy on the modifier of a - composable and pass a value from the TouchPrivacy enum. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a touch privacy override on your view
-Column(modifier = Modifier
-  .padding(16.dp)
-  .sessionReplayTouchPrivacy(touchPrivacy = TouchPrivacy.HIDE)){
-  // Content
-}
-
-
-
-
-
-
-

- To override touch privacy in UIKit views, use - dd.sessionReplayOverrides.touchPrivacy on a view instance - and set a value from the TouchPrivacyLevel enum. Setting it - to nil removes the override. -

-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
// Set a touch override on your view
-myView.dd.sessionReplayOverrides.touchPrivacy = .hide
-// Remove a touch override from your view
-myView.dd.sessionReplayOverrides.touchPrivacy = nil
-
-
-
-
-

- To override touch privacy in SwiftUI, wrap your content with - SessionReplayPrivacyView and configure the - touchPrivacy parameter. -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct SettingsView: View {
-    @State private var sliderValue = 0.5
-
-    var body: some View {
-        // Set a touch privacy override on your SwiftUI content
-        SessionReplayPrivacyView(touchPrivacy: .hide) {
-            VStack(spacing: 20) {
-                Button("Some Action") {
-                    // Handle action
-                }
-                .padding()
-                .background(Color.blue)
-                .foregroundColor(.white)
-                .cornerRadius(8)
-
-                Slider(value: $sliderValue, in: 0...1) {
-                    Text("Some Value")
-                }
-            }
-            .padding()
-        }
-    }
-}
-
-
-
-
-
-
-

- To override touch privacy in Flutter, use the - SessionReplayPrivacy widget to override the privacy - settings for an entire widget tree. Setting any value to - null keeps the privacy values unchanged from values - provided higher up the widget tree. -

-

- Enabling touch privacy affects the entire widget tree, and cannot be - toggled back to "show" in children. -

-
-
-
-
-
-
-
-
-
- -
-
-
class MyWidget: StatelessWidget {
-  Widget build() {
-    return SessionReplayPrivacy(
-      touchPrivacyLevel: TouchPrivacyLevel.hide,
-      child: PinPadWidget(),
-    );
-  }
-}
-
-
-
-
-
-

Hidden elements override

-

- For sensitive elements that need to be completely hidden, use the - hidden setting. -

-

- When an element is hidden, it is replaced by a placeholder - labeled as "Hidden" in the replay, and its subviews are not - recorded. -

-

- Note: Marking a view as hidden does not - prevent touch interactions from being recorded on that element. To hide - touch interactions as well, use the - touch override in addition to marking the - element as hidden. -

-
-

- Use setSessionReplayHidden(hide = true) to hide the - element. Setting hide to false removes the - override. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Mark a view as hidden
-myView.setSessionReplayHidden(hide = true)
-// Remove the override from the view
-myView.setSessionReplayHidden(hide = false)
-
-
-
-
-

- Use Modifier.sessionReplayHide to hide the element in - Jetpack Compose. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Mark a Column as hidden
-Column(modifier = Modifier
-  .padding(16.dp)
-  .sessionReplayHide(hide = true)){
-  // Content
-}
-
-
-
-
-
-
-

- In UIKit views, use dd.sessionReplayOverrides.hide to hide - the element: -

-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
// Mark a view as hidden
-myView.dd.sessionReplayOverrides.hide = true
-// Remove the override from the view
-myView.dd.sessionReplayOverrides.hide = false
-
-
-
-
-

- In SwiftUI, wrap your content with - SessionReplayPrivacyView and set the - hide parameter to true: -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct PaymentView: View {
-    @State private var cardNumber = ""
-    @State private var cvv = ""
-
-    var body: some View {
-        // Mark SwiftUI content as hidden
-        SessionReplayPrivacyView(hide: true) {
-            VStack(spacing: 16) {
-                Text("Payment Information")
-                    .font(.headline)
-
-                TextField("Card Number", text: $cardNumber)
-                    .textFieldStyle(RoundedBorderTextFieldStyle())
-
-                SecureField("CVV", text: $cvv)
-                    .textFieldStyle(RoundedBorderTextFieldStyle())
-
-                Text("Card ending in 1234")
-                    .foregroundColor(.secondary)
-            }
-            .padding()
-        }
-    }
-}
-
-
-
-
-

- Note: Setting the hidden override to - nil or false has the same effect—it disables - the override. -

-

- Combining privacy settings in SwiftUI -

-

- Combine multiple privacy settings in one - SessionReplayPrivacyView for different configurations. - Datadog recommends - combining options in a single view rather than nesting multiple - instances - to avoid adding unnecessary view layers. -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct UserProfileView: View {
-    @State private var userBio = ""
-    @State private var cardNumber = ""
-
-    var body: some View {
-        VStack(spacing: 30) {
-            // Preferred: Combine multiple privacy settings in one view
-            SessionReplayPrivacyView(
-                textAndInputPrivacy: .maskSensitiveInputs,
-                imagePrivacy: .maskNonBundledOnly,
-                touchPrivacy: .show
-            ) {
-                VStack(spacing: 20) {
-                    // User profile section
-                    HStack {
-                        AsyncImage(url: URL(string: "https://example.com/profile.jpg")) { image in
-                            image.resizable()
-                        } placeholder: {
-                            Circle().fill(Color.gray.opacity(0.3))
-                        }
-                        .frame(width: 60, height: 60)
-                        .clipShape(Circle())
-
-                        VStack(alignment: .leading) {
-                            Text("John Doe")
-                                .font(.headline)
-                            TextField("Enter bio", text: $userBio)
-                                .textFieldStyle(RoundedBorderTextFieldStyle())
-                        }
-                    }
-
-                    Button("Save Profile") {
-                        // Save action
-                        print("Profile saved")
-                    }
-                    .padding()
-                    .background(Color.blue)
-                    .foregroundColor(.white)
-                    .cornerRadius(8)
-                }
-                .padding()
-            }
-
-            // For completely different privacy requirements, use separate `SessionReplayPrivacyView` instances
-            SessionReplayPrivacyView(hide: true) {
-                VStack(spacing: 16) {
-                    Text("Credit Card Information")
-                        .font(.headline)
-                    TextField("Card Number", text: $cardNumber)
-                        .textFieldStyle(RoundedBorderTextFieldStyle())
-                }
-                .padding()
-                .background(Color.gray.opacity(0.1))
-                .cornerRadius(8)
-            }
-        }
-        .padding()
-    }
-}
-
-
-
-
-

- Note: Each - SessionReplayPrivacyView introduces an additional native - view layer. For optimal performance, prefer combining privacy settings - instead of nesting multiple privacy views when possible. -

-
-
-

- To hide a widget tree in Flutter, use the - SessionReplayPrivacy widget to override the privacy - settings for an entire widget tree. -

-

- Hiding a widget tree affects the entire widget tree, and cannot be - toggled back to false in children, as Session Replay stops - processing widget trees that are marked with hide. -

-
-
-
-
-
-
-
-
-
- -
-
-
class MyWidget: StatelessWidget {
-  Widget build() {
-    return SessionReplayPrivacy(
-      hide: true,
-      child: PinPadWidget(),
-    );
-  }
-}
-
-
-
-
-
-
-
-

- Privacy overrides are fully supported in React Native starting from - version 2.8.0 of the Datadog - React Native SDK. Although the underlying functionality is shared with native Android and - iOS platforms, the integration in React Native is designed to align with - common React patterns. -

-

Behavior consistency

-

- React Native's implementation is built on the same foundation as the - native Android and iOS SDKs. As a result, you can rely on the privacy - features behaving the same way across all three platforms. -

-

Usage with SessionReplayView

-

- The SDK provides a set of React components under the - SessionReplayView namespace, which are used to configure - privacy settings within your React Native application. -

-

To use them, import SessionReplayView as follows:

-
-
-

App.tsx

-
-
-
- -
-
-
import { SessionReplayView } from "@datadog/mobile-react-native-session-replay";
-
-
-
-
-

This import provides access to four privacy-focused components.

-

- Each of these components behaves like a regular React Native View, meaning - they can be used anywhere you would typically use a View, with the - addition of privacy-related behavior. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ComponentDescriptionProperties
SessionReplayView.Privacy - Adds support for customizing text, image, and touch privacy settings - for its children. - - -
SessionReplayView.MaskAll - Applies the most restrictive privacy settings (MaskAll - or platform equivalent) to all children. - -
    -
  • showTouch?: boolean
  • -
-
SessionReplayView.MaskNone - Applies the least restrictive settings (MaskNone or - platform equivalent). All child components are visible. - (No additional properties)
SessionReplayView.HideCompletely hides all child components from session replay.(No additional properties)
-

Integration approaches

-

There are two ways to apply privacy overrides in React Native:

-
    -
  • - Wrap specific components with a privacy-focused - SessionReplayView to target only certain elements, or -
  • -
  • - Replace an entire <View> with a - SessionReplayView to apply privacy settings to a whole - section of your UI. -
  • -
-

- This flexibility lets you control which parts of your app are masked or - visible in session replays. -

-
- -
-
-

- Use SessionReplayView components to wrap specific parts - of your UI where you want to override privacy settings. -

-

For example, going from:

-
-
-

App.tsx

-
-
-
- -
-
-
const App = () => {
-  return (
-    <View>
-      {/* content */}
-      <TextInput placeholder="First Name" value="Data" />
-      <TextInput placeholder="Last Name" value="Dog" />
-      {/* content */}
-    </View>
-  );
-}
-
-
-
-
-

To:

-
-
-

App.tsx

-
-
-
- -
-
-
const App = () => {
-  return (
-    <View>
-      {/* content */}
-      <SessionReplayView.MaskAll showTouch={true}>
-      <TextInput placeholder="First Name" value="Data" />
-      <TextInput placeholder="Last Name" value="Dog" />
-      </SessionReplayView.MaskAll>
-      {/* content */}
-    </View>
-  );
-}
-
-
-
-
-
-
-

- Replace an existing <View> with a - SessionReplayView component directly. This is ideal - when a view already encapsulates the section of the UI that needs - modified privacy behavior. -

-

For example, instead of:

-
-
-

App.tsx

-
-
-
- -
-
-
const App = () => {
-  return (
-    <View>
-      {/* content */}
-    </View>
-  );
-}
-
-
-
-
-

You can use:

-
-
-

App.tsx

-
-
-
- -
-
-
const App = () => {
-  return (
-    <SessionReplayView.MaskNone>
-      {/* content */}
-    </SessionReplayView.MaskNone>
-  );
-}
-
-
-
-
-
-
-
-

Combining privacy components

-

- You can freely combine the SessionReplayView components to - apply different privacy settings to distinct sections of your UI. This is - especially useful when you need a mix of hidden elements, masked input - fields, and visible content within the same screen. -

-

For example:

-
-
-

App.tsx

-
-
-
- -
-
-
import { ImagePrivacyLevel, SessionReplayView, TextAndInputPrivacyLevel, TouchPrivacyLevel } from "@datadog/mobile-react-native-session-replay";
-
-const App = () => {
-  return (
-    <SessionReplayView.Privacy
-      textAndInputPrivacy={TextAndInputPrivacyLevel.MASK_SENSITIVE_INPUTS}
-      imagePrivacy={ImagePrivacyLevel.MASK_NONE}
-      touchPrivacy={TouchPrivacyLevel.SHOW}>
-      {/* content */}
-      <SessionReplayView.MaskAll showTouch={true}>
-        {/* content */}
-        <SessionReplayView.MaskNone>
-          {/* content */}
-        </SessionReplayView.MaskNone>
-        {/* content */}
-      </SessionReplayView.MaskAll>
-        {/* content */}
-      <SessionReplayView.Hide>
-        {/* content */}
-      </SessionReplayView.Hide>
-    </SessionReplayView.Privacy>
-  );
-}
-
-
-
-
-
-

Notes on WebViews

- -

How and what data is masked

-

- This section describes how the Datadog recorder handles masking based on - data type and how that data is defined. -

-

Text masking strategies

-

- Depending on how you've configured your privacy settings, the type of text, - and sensitivity of data, Datadog's masking rules apply different strategies - to different types of text fields. -

- - - - - - - - - - - - - - - - - - - - - - - - - -
Text masking strategyDescriptionExample
No maskThe text is revealed in the session replay - "Hello world" → - "Hello world" -
Space-preserving mask - Each visible character is replaced with a lowercase "x" - - "Hello world" → - "xxxxx xxxxx" -
Fixed-length mask - The entire text field is replaced with a constant of three asterisks - (***) - - "Hello world""***" -
-

- With the above text strategies in mind, you have a few different options if - you want to override the default privacy rule of mask in your - configuration. -

-

- The following chart shows how Datadog applies different text masking - strategies, using the rules you set up in your configuration, to the below - text types. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeAllow allMask allMask user input
Sensitive textFixed-length maskFixed-length maskFixed-length mask
Input and option textNo maskFixed-length maskFixed-length mask
Static textNo maskSpace-preserving maskNo mask
Hint textNo maskFixed-length maskNo mask
-

Text masking definitions

-

- Find below a description of how Datadog's recorder treats each text type. -

-

Sensitive text

-

- Sensitive text includes passwords, e-mails, and phone numbers marked in a - platform-specific way, and other forms of sensitivity in text available to - each platform. -

-
-

Sensitive text can be detected in:

-
    -
  • Edit Text
  • -
  • Address information
  • -
-
-
-

Sensitive text can be detected in:

-
    -
  • Text Field
  • -
  • Text View
  • -
  • Address information
  • -
  • Credit card numbers
  • -
  • One-time codes
  • -
-
-
-

Sensitive text can be detected in the following components.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ComponentPlatform(s)
Text FieldiOS
Text ViewiOS
Edit TextAndroid
Address informationiOS, Android
Credit card numbersiOS
One-time codesiOS
-
- - - - - - - - - - - - -
TextInputType.nameTextInputType.phoneTextInputType.emailAddressTextInputType.streetAddressTextInputType.twitterTextInputType.visiblePassword
-

Input and option text

-

- Input and option text is text entered by the user with a keyboard or other - text-input device, or a custom (non-generic) value in selection elements. -

-

This includes the below.

-
-
    -
  • - User-entered text in: -
      -
    • Text Field
    • -
    • Text View
    • -
    -
  • -
  • - User-selected options in: -
      -
    • Value Picker
    • -
    • Segment
    • -
    -
  • -
  • - Notable exclusions: -
      -
    • - Placeholder (hint) texts in Text Field and Text View (not entered by - the user) -
    • -
    • Non-editable texts in Text View
    • -
    • Month, day, and year labels in Date Picker (generic values)
    • -
    -
  • -
-
-
-
    -
  • - User-entered text in: -
      -
    • Edit Text
    • -
    -
  • -
  • - User-selected options in: -
      -
    • Value Picker
    • -
    • Drop Down List
    • -
    -
  • -
  • - Notable exclusions: -
      -
    • - Placeholder (hint) texts in Edit Text (not entered by the user) -
    • -
    • Month, day, and year labels in Date Picker (generic values)
    • -
    -
  • -
-
-
-
    -
  • - User-entered text in: -
      -
    • Text Field (iOS)
    • -
    • Text View (iOS)
    • -
    • Edit Text (Android)
    • -
    -
  • -
  • - User-selected options in: -
      -
    • Value Picker (iOS + Android)
    • -
    • Segment (iOS)
    • -
    • Drop Down List (Android)
    • -
    -
  • -
  • - Notable exclusions: -
      -
    • - Placeholder (hint) texts in Text Field, Text View and Edit Text (not - entered by the user) -
    • -
    • Non-editable texts in Text View (iOS).
    • -
    • Month, day, and year labels in Date Picker (generic values)
    • -
    -
  • -
-
-
-
    -
  • - User-entered text in EditableText, which is used in: -
      -
    • TextField
    • -
    • CupertinoTextField
    • -
    • many custom TextField implementations
    • -
    -
  • -
  • - Notable exclusions: -
      -
    • - Placeholder (hint) texts in Text Field and Text View (not entered by - the user) -
    • -
    • Text in Text Decorations (not entered by the user)
    • -
    • Month, day, and year labels in Date Picker (generic values)
    • -
    -
  • -
-
-

Static text

-

- Static text is any text that is not directly entered by the user. This - includes the below. -

-

All texts in:

-
-
    -
  • Texts in non-editable Text View
  • -
  • Month, day, and year labels in the date and time picker
  • -
  • - Values updated in response to gesture interaction with input elements, - such as the current value of the Slider -
  • -
  • - Other controls, not considered as "user input elements", such - as Labels, Tab Bar, and Navigation Bar -
  • -
-
-
-
    -
  • Checkbox and Radio Button titles
  • -
  • Month, day, and year labels in the date and time picker
  • -
  • - Values updated in response to gesture interaction with input elements, - such as the current value of the Slider -
  • -
  • - Other controls, not considered as "user input elements", such - as Tabs -
  • -
-
-
-
    -
  • Checkbox and Radio Button titles (Android)
  • -
  • Texts in non-editable Text View (iOS)
  • -
  • Month, day and year labels in the date and time picker
  • -
  • - Values updated in response to gesture interaction with input elements, - such as the current value of the Slider -
  • -
  • - Other controls, not considered as "user input elements", such - as Labels, Tab Bar, and Navigation Bar (iOS), or Tabs (Android) -
  • -
-
-
-
    -
  • Checkbox and Radio Button titles
  • -
  • Month, day and year labels in the date and time picker
  • -
  • - Values updated in response to gesture interaction with input elements, - such as the current value of the Slider -
  • -
  • - Other controls, not considered as "user input elements", such - as Text, Tab Bar, and Bottom Navigation Bar -
  • -
-
-

Hint text

-

- Hint text is static text in editable text elements or option selectors that - is displayed when no value is given. This includes: -

-
-
    -
  • Placeholders in Text Field
  • -
  • Placeholders in Text View
  • -
-
-
-
    -
  • Hints in Edit Text
  • -
  • Prompts in Drop Down lists
  • -
-
-
-
    -
  • Placeholders in Text Field (iOS), Text View (iOS)
  • -
  • Hints in Edit Text (Android)
  • -
  • Prompts in Drop Down lists (Android)
  • -
-
-
-
    -
  • InputDecoration elements in TextView
  • -
  • Placeholder text in CupertinoTextField
  • -
-
-

Appearance masking

-

- The following chart shows how we apply different appearance masking - strategies, using the rules you set up in your configuration, to the below - text types. -

- - - - - - - - - - - - - - - - - - - - - - - -
TypeAllow allMask allMask user input
Revealing attributes
Other attributes
-

Revealing attributes

-

- Revealing attributes are attributes that can reveal or suggest the value of - input elements and can be used to infer a user's input or selection. -

-

This includes:

-
-

Shapes

-
    -
  • Background of selected option in Segment
  • -
  • Circle surrounding the selected date in a Date Picker
  • -
  • Thumb of a Slider
  • -
-

Text attributes

-
    -
  • The color of a label rendering the selected date in Date Picker
  • -
  • The position of the first and last option in Value Picker
  • -
-
-
-

Shapes

-
    -
  • Selection mark in Checkbox
  • -
  • Thumb of a Slider
  • -
-

Text attributes

-
    -
  • The position of the first and last option in Value Picker
  • -
-
-
-

Shapes

- - - - - - - - - - - - - - - - - - - - - - - - - -
TypePlatform(s)
Background of selected option in SegmentiOS
Circle surrounding the selected date in Date PickeriOS
Selection mark in CheckboxAndroid
Thumb of a SlideriOS, Android
-

Text attributes

- - - - - - - - - - - - - - - - - -
TypePlatform(s)
- The color of a label rendering the selected date in Date Picker - iOS
The position of the first and last option in Value PickeriOS, Android
-
-
-

Shapes

-
    -
  • Background of selected option in Segment
  • -
  • Circle surrounding the selected date in a Date Picker
  • -
  • Thumb of a Slider
  • -
-

Text attributes

-
    -
  • The color of a label rendering the selected date in Date Picker
  • -
  • The position of the first and last option in Value Picker
  • -
-
-

Touch interactions

-

- The following chart shows how we apply different touch interaction - strategies, using the rules you set up in your configuration, to the below - text types. While any interaction that happens on an on-screen keyboard is - masked, interactions with other elements are not masked. -

- - - - - - - - - - - - - - - - - - - - - - - -
TypeAllow allMask allMask user input
Other attributes
On-screen keyboard
-

Image masking

-

- The following chart shows how we apply different image masking strategies: -

- - - - - - - - - - - - - - - - - - - - - - - -
TypeMask None -
Mask Large Only
-
- Mask Non Bundled Only -
-
- Mark Large Only (Android) / Mask Non Bundled Only (iOS) -
-
Mask All
Content ImageShownMaskedMasked
System ImageShownShownMasked
-

Further reading

-
-
- -{{< img src="real_user_monitoring/session_replay/mobile/masking-mode-mask-all-2.png" style="display:none;" alt="" >}} -{{< img src="real_user_monitoring/session_replay/mobile/masking-image-mask-all.png" style="display:none;" alt="" >}} -{{< img src="real_user_monitoring/session_replay/mobile/masking-image-mask-large-only.png" style="display:none;" alt="" >}} -{{< img src="real_user_monitoring/session_replay/mobile/masking-image-mask-non-bundled-only.png" style="display:none;" alt="" >}} - diff --git a/content/en/product_analytics/session_replay/mobile/setup_and_configuration.md b/content/en/product_analytics/session_replay/mobile/setup_and_configuration.md deleted file mode 100644 index 42596031bf3..00000000000 --- a/content/en/product_analytics/session_replay/mobile/setup_and_configuration.md +++ /dev/null @@ -1,1243 +0,0 @@ ---- -title: Mobile Session Replay Setup and Configuration -description: Setting up and configuring Mobile Session Replay. -further_reading: - - link: /product_analytics/session_replay/mobile - tag: Documentation - text: Mobile Session Replay - - link: /product_analytics/session_replay/mobile/app_performance - tag: Documentation - text: How Mobile Session Replay Impacts App Performance - - link: /product_analytics/session_replay/mobile/privacy_options - tag: Documentation - text: Mobile Session Replay Privacy Options - - link: /product_analytics/session_replay/mobile/troubleshooting - tag: Documentation - text: Troubleshoot Mobile Session Replay - - link: /product_analytics/session_replay - tag: Documentation - text: Session Replay ---- -

SDK


-

Setup

-
-

- All Session Replay SDK versions can be found in the - Maven Central Repository. -

-

To set up Mobile Session Replay for Android:

-

- Step 1 - Set up the Android RUM SDK -

-

- Make sure you've - set up and initialized the Datadog Android RUM SDK - with views instrumentation enabled. -

-

- Step 2 - Declare the Datadog Session Replay as a dependency -

-
-
-

build.gradle.kts

-
-
-
- -
-
-
implementation("com.datadoghq:dd-sdk-android-rum:[datadog_version]")
-implementation("com.datadoghq:dd-sdk-android-session-replay:[datadog_version]")
-// in case you need Material support
-implementation("com.datadoghq:dd-sdk-android-session-replay-material:[datadog_version]")
-// in case you need Jetpack Compose support
-implementation("com.datadoghq:dd-sdk-android-session-replay-compose:[datadog_version]")
-
-
-
-
-

Step 3 - Enable Session Replay

-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  // in case you need Material extension support
-  .addExtensionSupport(MaterialExtensionSupport())
-  // in case you need Jetpack Compose support
-  .addExtensionSupport(ComposeExtensionSupport())
-  .build()
-
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-

To set up Mobile Session Replay for iOS:

-

Step 1 - Set up the iOS RUM SDK

-

- Make sure you've - set up and initialized the Datadog iOS RUM SDK - with views instrumentation enabled. -

-

- Step 2 - Declare the Datadog Session Replay as a dependency -

-
- -
-
-

- Add DatadogSessionReplay library as a dependency to - your app target. -

-
-
-

- Add pod 'DatadogSessionReplay to your - Podfile. -

-
-
-

- Add DatadogSessionReplay.xcframework as a dependency to - your app target. -

-
-
-
-

Step 3 - Enable Session Replay

-
-
-

AppDelegate.swift

-
-
-
- -
-
-
import DatadogSessionReplay
-
-SessionReplay.enable(
-  with: SessionReplay.Configuration(
-    replaySampleRate: sampleRate,
-    // Enable the experimental SwiftUI recording
-    featureFlags: [.swiftui: true]
-  )
-)
-
-
-
-
-
-
-

- All Session Replay SDK versions can be found in the - Maven Central Repository. -

-

To set up Mobile Session Replay for Kotlin Multiplatform:

-

- Step 1 - Set up the Kotlin Multiplatform RUM SDK -

-

- Make sure you've - set up and initialized the Datadog Kotlin Multiplatform RUM SDK - with views instrumentation enabled. -

-

- Step 2 - Add the DatadogSessionReplay iOS library as a - link-only dependency -

-

- For instructions, see the - guide. -

-

- Step 3 - Declare Datadog Session Replay as a dependency -

-
-
-

build.gradle.kts

-
-
-
- -
-
-
kotlin {
-  sourceSets {
-    commonMain.dependencies {
-      implementation("com.datadoghq:dd-sdk-kotlin-multiplatform-rum:[datadog_version]")
-      implementation("com.datadoghq:dd-sdk-kotlin-multiplatform-session-replay:[datadog_version]")
-    }
-
-    // in case you need Material support on Android
-    androidMain.dependencies {
-      implementation("com.datadoghq:dd-sdk-android-session-replay-material:[datadog_version]")
-    }
-  }
-}
-
-
-
-
-

Step 4 - Enable Session Replay

-
-
-

Application.kt

-
-
-
- -
-
-
// in common source set
-val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-

- Step 5 - Set up Material support on Android (Optional) -

-

If your app uses Material on Android, add:

-
-
-
-
- -
-
-
SessionReplayConfiguration.Builder.addExtensionSupport(MaterialExtensionSupport())
-
-
-
-
-
-
-
-

- To enable Session Replay, you must use at least version - 2.0.4 of the Datadog - React Native SDK, and ensure that the Session Replay SDK version matches the React - Native SDK version you are using. -

-
-

- All Session Replay SDK versions can be found in the - npmjs repository. -

-

To set up Mobile Session Replay for React Native:

-

- Step 1 - Set up the React Native SDK -

-

- Make sure you've - set up and initialized the Datadog React Native SDK - with views instrumentation enabled. -

-

- Step 2 - Declare the React Native Session Replay as a dependency -

-

- Add the - @datadog/mobile-react-native-session-replay dependency, and - make sure it matches the - @datadog/mobile-react-native version, either through - npm - or - yarn. -

-
- -
-
-
-
-
-
- -
-
-
npm install @datadog/mobile-react-native-session-replay
-
-
-
-
-
-
-
-
-
-
- -
-
-
yarn add @datadog/mobile-react-native-session-replay
-
-
-
-
-
-
-
-

Step 3 - Enable Session Replay

-

- After the Datadog React Native SDK and Session Replay SDK dependencies are - imported, you can enable the feature when configuring the SDK. -

-
- -
-
-

If you use the DatadogProvider component:

-
-
-

App.tsx

-
-
-
- -
-
-
import { DatadogProvider, DatadogProviderConfiguration } from "@datadog/mobile-react-native";
-import {
-  ImagePrivacyLevel,
-  SessionReplay,
-  TextAndInputPrivacyLevel,
-  TouchPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const configuration = new DatadogProviderConfiguration(/* ... */)
-
-// Add this function as onInitialization prop to DatadogProvider
-const onSDKInitialized = async () => {
-  await SessionReplay.enable({
-    replaySampleRate: 100, // Session Replay will be available for all sessions already captured by the SDK
-    textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_SENSITIVE_INPUTS,
-    imagePrivacyLevel: ImagePrivacyLevel.MASK_NONE,
-    touchPrivacyLevel: TouchPrivacyLevel.SHOW,
-  });
-};
-
-const App = () => {
-  const navigationRef = React.useRef(null);
-  return (
-    <DatadogProvider configuration={configuration} onInitialization={onSDKInitialized}>
-      {/* App */}
-    </DatadogProvider>
-  );
-};
-
-export default App;
-
-
-
-
-
-
-

If you use the DdSdkReactNative.initialize method:

-
-
-

App.tsx

-
-
-
- -
-
-
import { DdSdkReactNative, DdSdkReactNativeConfiguration } from "@datadog/mobile-react-native";
-import { SessionReplay } from "@datadog/mobile-react-native-session-replay";
-
-const configuration = new DdSdkReactNativeConfiguration(/* ... */)
-
-DdSdkReactNative.initialize(configuration)
-  .then(() => SessionReplay.enable({
-    replaySampleRate: 100, // Session Replay will be available for all sessions already captured by the SDK
-    textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_SENSITIVE_INPUTS,
-    imagePrivacyLevel: ImagePrivacyLevel.MASK_NONE,
-    touchPrivacyLevel: TouchPrivacyLevel.SHOW,
-  }))
-  .catch((error) => { /* handle error */ });
-
-
-
-
-
-
-
-

- During this step, you can also configure multiple - privacy levels - that apply to Session Replays. -

-

- Step 4 - (iOS only) Update your iOS pods. -

-
-
-
-
- -
-
-
cd ios && pod install
-
-
-
-
-

Step 5 - Rebuild your app

-

Rebuild your iOS and Android apps

-
-
-
-

Datadog Session Replay for Flutter is currently in Preview.

-
-

- All Session Replay SDK versions can be found in - Pub. -

-

To set up Datadog Session Replay for Flutter:

-

- Step 1 - Set up the Flutter plugin -

-

- Make sure you have - set up and initialized the Datadog Flutter Plugin. -

-

- Step 2 - Add the package to your pubspec.yaml -

-
-
-

pubspec.yaml

-
-
-
- -
-
-
packages:
-  # other packages
-  datadog_session_replay: ^x.x.x
-
-
-
-
-

- Step 3 - Enable Session Replay in your DatadogConfiguration -

-
-
-
-
- -
-
-
import 'package:datadog_session_replay/datadog_session_replay.dart';
-
-// ....
-final configuration = DatadogConfiguration(
-    // Normal Datadog configuration
-    clientToken: 'client-token',
-    // RUM is required to use Datadog Session Replay
-    rumConfiguration: RumConfiguration(
-        applicationId: '<application-id'>
-    ),
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        // Setup default text, image, and touch privacy
-        textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskSensitiveInputs,
-        touchPrivacyLevel: TouchPrivacyLevel.show,
-        // Setup session replay sample rate.
-        replaySampleRate: 100.0,
-    ),
-);
-
-
-
-
-

- Step 4 - Add a SessionReplayCapture to the root of your Widget tree -

-

- Add a SessionReplayCapture widget to the root of your Widget tree, above - your MaterialApp or similar application widget. -

-
-
-
-
- -
-
-
class MyApp extends StatefulWidget {
-  const MyApp({super.key});
-
-  @override
-  State<MyApp> createState() => _MyAppState();
-}
-
-class _MyAppState extends State<MyApp> {
-  // Note a key is required for SessionReplayCapture
-  final captureKey = GlobalKey();
-
-  // Other App Configuration
-
-  @override
-  Widget build(BuildContext context) {
-    return SessionReplayCapture(
-      key: captureKey,
-      rum: DatadogSdk.instance.rum!,
-      sessionReplay: DatadogSessionReplay.instance!,
-      child: MaterialApp.router(color: color, routerConfig: router),
-    );
-  }
-}
-
-
-
-
-
-

Web view instrumentation

-

- You can record the entire user journey across both - web and native views - on iOS or Android and watch it in a single Session Replay. -

-

- The Session Replay is recorded through the Browser SDK, then the Mobile SDK - handles the batching and uploading of the webview recording. -

-
-

- To instrument your consolidated web and native Session Replay views for - Android: -

-
    -
  1. - Ensure you are using version - 2.8.0 - or higher of the Android SDK. -
  2. -
  3. - Enable - webview tracking - for your mobile application. -
  4. -
  5. - Enable - Session Replay - for your web application. -
  6. -
  7. - Enable Session Replay for your mobile application (see setup - instructions above). -
  8. -
-
-
-

- To instrument your consolidated web and native Session Replay views for - iOS: -

-
    -
  1. - Ensure you are using version - 2.13.0 - or higher of the iOS SDK. -
  2. -
  3. - Enable - webview tracking - for your mobile application. -
  4. -
  5. - Enable - Session Replay - for your web application. -
  6. -
  7. - Enable Session Replay for your mobile application (see setup - instructions above). -
  8. -
-
-
-

- To instrument your consolidated web and native Session Replay views for - Kotlin Multiplatform: -

-
    -
  1. - Enable - webview tracking - for your mobile application. -
  2. -
  3. - Enable - Session Replay - for your web application. -
  4. -
  5. - Enable Session Replay for your mobile application (see setup - instructions above). -
  6. -
-
-
-

- To instrument your consolidated web and native Session Replay views for - React Native: -

-
    -
  1. - Enable - webview tracking - for your React Native application. -
  2. -
  3. - Enable - Session Replay - for your web application. -
  4. -
  5. - Enable Session Replay for your mobile application (see setup - instructions above). -
  6. -
-

- Note: This feature is not compatible with React Native's - New Architecture - for Android. -

-
-
-

- Datadog Session Replay for Flutter does not currently support Web view - capture. -

-
-

Additional configuration

-

- Set the sample rate for recorded sessions to appear -

-

- The sample rate is an optional parameter in the Session Replay - configuration. It must be a number between 0.0 and 100.0, where 0 indicates - that no replays are recorded and 100 means that all sessions include a - replay. If the sample rate is not specified in the configuration, the - default value of 100 is applied. -

-

- This sample rate is applied in addition to the RUM sample rate. For example, - if RUM uses a sample rate of 80% and Session Replay uses a sample rate of - 20%, it means that out of all user sessions, 80% are included in RUM, and - within those sessions, only 20% have replays. -

-
-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder(<SAMPLE_RATE>)
-  ...
-  .build()
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
- -
-
-
var sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: <SAMPLE_RATE>
-)
-
-
-
-
-
-
-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder(<SAMPLE_RATE>)
-  ...
-  .build()
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
- -
-
-
import { SessionReplay } from "@datadog/mobile-react-native-session-replay";
-
-SessionReplay.enable({
-  replaySampleRate: <SAMPLE_RATE>
-});
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-  // ...
-)..enableSessionReplay(
-  DatadogSessionReplayConfiguration(
-    replaySampleRate: <SAMPLE_RATE>
-  )
-);
-
-
-
-
-
-

- Start or stop the recording manually -

-

- By default, Session Replay starts recording automatically. However, if you - prefer to manually start recording at a specific point in your application, - you can use the optional startRecordingImmediately parameter as - shown below, and later call SessionReplay.startRecording(). You - can also use SessionReplay.stopRecording() to stop the - recording anytime. -

-
-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder(<SAMPLE_RATE>)
-  .startRecordingImmediately(false)
-  .build()
-// Do something
-SessionReplay.startRecording()
-SessionReplay.stopRecording()
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: <SAMPLE_RATE>,
-  startRecordingImmediately: false
-)
-
-// Do something
-SessionReplay.startRecording()
-SessionReplay.stopRecording()
-
-
-
-
-
-
-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder(<SAMPLE_RATE>)
-  .startRecordingImmediately(false)
-  .build()
-
-// Do something
-SessionReplay.startRecording()
-SessionReplay.stopRecording()
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
- -
-
-
import { SessionReplay } from "@datadog/mobile-react-native-session-replay";
-
-SessionReplay.enable({
-  replaySampleRate: sampleRate,
-  startRecordingImmediately: false
-});
-// Do something
-SessionReplay.startRecording();
-SessionReplay.stopRecording();
-
-
-
-
-
-
-

- Datadog Session Replay for Flutter does not currently support manual - recording. -

-
-

- Validate whether Session Replay data is being sent -

-

- To validate whether Session Replay data is being sent from the app, you can - enable debug option in Datadog SDK. -

-
-
-
-

Application.kt

-
-
-
- -
-
-
Datadog.setVerbosity(Log.DEBUG)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
- -
-
-
Datadog.verbosityLevel = .debug
-
-
-
-
-

- If everything is fine, following logs should appear in the Xcode debug - console in about 30 seconds after launching the app: -

-
-
-

Xcode console

-
-
-
- -
-
-
[DATADOG SDK] 🐶 → 10:21:29.812 ⏳ (session-replay) Uploading batch...
-[DATADOG SDK] 🐶 → 10:21:30.442    → (session-replay) accepted, won't be retransmitted: [response code: 202 (accepted), request ID: BD445EA-...-8AFCD3F3D16]
-
-
-
-
-
-
-
-
-

Application.kt

-
-
-
- -
-
-
Datadog.setVerbosity(SdkLogVerbosity.DEBUG)
-
-
-
-
-
-
-

Set the verbosity to DEBUG when you initialize the SDK:

-
-
-

App.tsx

-
-
-
- -
-
-
import { SdkVerbosity } from "@datadog/mobile-react-native";
-
-...
-
-config.verbosity = SdkVerbosity.DEBUG;
-
-
-
-
-
-
-

- Set the SDKs verbosity to CoreLoggerLevel.debug before you - initialize the SDK: -

-
-
-
-
- -
-
-
DatadogSdk.instance.sdkVerbosity = CoreLoggerLevel.debug;
-
-
-
-
-
-

Privacy options

-

- See - Privacy Options. -

-

Further reading

-
-
\ No newline at end of file diff --git a/content/en/real_user_monitoring/session_replay/mobile/privacy_options.md b/content/en/real_user_monitoring/session_replay/mobile/privacy_options.md deleted file mode 100644 index 0db3b50f0ef..00000000000 --- a/content/en/real_user_monitoring/session_replay/mobile/privacy_options.md +++ /dev/null @@ -1,3091 +0,0 @@ ---- -title: Mobile Session Replay Privacy Options -description: Configure privacy options for Mobile Session Replay. -further_reading: - - link: /real_user_monitoring/session_replay/mobile - tag: Documentation - text: Mobile Session Replay - - link: /real_user_monitoring/session_replay/mobile/app_performance - tag: Documentation - text: How Mobile Session Replay Impacts App Performance - - link: /real_user_monitoring/session_replay/mobile/setup_and_configuration - tag: Documentation - text: Setup and Configure Mobile Session Replay - - link: /real_user_monitoring/session_replay/mobile/troubleshooting - tag: Documentation - text: Troubleshoot Mobile Session Replay - - link: /real_user_monitoring/session_replay - tag: Documentation - text: Session Replay ---- -

SDK

SDK


-

Overview

-

- Session Replay provides privacy controls to ensure organizations of any - scale do not expose sensitive or personal data. Data is stored on - Datadog-managed cloud instances and encrypted at rest. -

-

- Default privacy options for Session Replay protect end user privacy and - prevent sensitive organizational information from being collected. -

-

- By enabling Mobile Session Replay, you can automatically mask sensitive - elements from being recorded through the RUM Mobile SDK. When data is - masked, that data is not collected in its original form by Datadog's SDKs - and thus is not sent to the backend. -

-

Fine-grained masking

-

- Using the masking modes below, you can override the default setup on a - per-application basis. Masking is fine-grained, which means you can override - masking for text and inputs, images, and touches individually to create a - custom configuration that suits your needs. -

-

Text and input masking

-

- By default, the mask_all setting is enabled for all data. With - this setting enabled, all text and input content on screen is masked, as - shown below. -

-
-
- What your application screen may resemble when `mask` is enabled. -
-

Mask sensitive inputs

-

- With the mask_sensitive_inputs setting enabled, all text and - inputs are shown except those considered sensitive (passwords, emails, and - phone numbers). -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setTextAndInputPrivacy(TextAndInputPrivacy.MASK_SENSITIVE_INPUTS)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: .maskSensitiveInputs,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TextAndInputPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_SENSITIVE_INPUTS,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskSensitiveInputs,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Mask all inputs

-

- With the mask_all_inputs setting enabled, all inputs fields are - masked in the replay. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-.setTextAndInputPrivacy(TextAndInputPrivacy.MASK_ALL_INPUTS)
-.build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: .maskAllInputs,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TextAndInputPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_ALL_INPUTS,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskAllInputs,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Mask all

-

- With the mask_all setting enabled, all text and input fields - are masked in the replay. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setTextAndInputPrivacy(TextAndInputPrivacy.MASK_ALL)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: .maskAll,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TextAndInputPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_ALL,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskAll,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Image masking

-

- By default, the mask_all setting is enabled for all images. - With this setting enabled, all images on screen are masked. -

-
-

- For performance reasons, large images (those exceeding 1000x1000 total - pixels) are masked in Flutter, and will display "Large Image" in - the Session Replay player. -

-
-

Mask all images

-

- With the mask_all setting enabled, all images are replaced by - placeholders labeled 'Image' in the replay. -

-
-
- What your application screen may resemble when `mask-all` is enabled. -
-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setImagePrivacy(ImagePrivacy.MASK_ALL)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: .maskAll,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  ImagePrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  imagePrivacyLevel: ImagePrivacyLevel.MASK_ALL,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        imagePrivacyLevel: ImagePrivacyLevel.maskAll,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Mask content images

-

- You can manage content masking while still allowing system or bundled images - to be visible. -

-
-

- Use the maskNonBundledOnly setting to replace non-bundled - images with a "Content Image" placeholder in the replay. -

-
    -
  • - In UIKit, the SDK can determine whether an image is bundled and can mask - it accordingly. -
  • -
  • - In SwiftUI, this determination isn't possible. Instead, the SDK uses a - heuristic: if an image exceeds 100×100 points, it is assumed to be - non-bundled and is masked. -
  • -
-
-
-

- Select the mask_large_only setting, which replaces images - with dimensions that exceed 100x100dp with a "Content Image" - placeholder. -

-

- Note: These dimensions refer to the drawable resource, - not the view's size. -

-
-
-
-
- What your application screen may resemble when `mask_large_only` is enabled on Android. -
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setImagePrivacy(ImagePrivacy.MASK_LARGE_ONLY)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
- What your application screen may resemble when `mask_non_bundled_only` is enabled on iOS. -
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: .maskNonBundledOnly,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  ImagePrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  imagePrivacyLevel: ImagePrivacyLevel.MASK_NON_BUNDLED_ONLY,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-

- Bundled images are those that use AssetImage as their image - provider. -

-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        imagePrivacyLevel: ImagePrivacyLevel.maskNonAssetsOnly,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Show all images

-

- With the mask_none setting enabled, all images are shown in the - replay. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setImagePrivacy(ImagePrivacy.MASK_NONE)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: .maskNone,
-  touchPrivacyLevel: touchPrivacyLevel
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  ImagePrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  imagePrivacyLevel: ImagePrivacyLevel.MASK_NONE,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-

Touch masking

-

- By default, the hide setting is enabled for all touches. With - this setting enabled, all touches on screen are hidden. -

-

Hide all touches

-

- With the hide setting enabled, all touches that occur during - the replay are hidden. This is the default setting. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setTouchPrivacy(TouchPrivacy.HIDE)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: .hide
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TouchPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  touchPrivacyLevel: TouchPrivacyLevel.HIDE,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        imagePrivacyLevel: ImagePrivacyLevel.maskNone,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Show all touches

-

- With the show setting enabled, all touches that occur during - the replay are shown. -

-
-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .setTouchPrivacy(TouchPrivacy.SHOW)
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: sampleRate,
-  textAndInputPrivacyLevel: textAndInputPrivacyLevel,
-  imagePrivacyLevel: imagePrivacyLevel,
-  touchPrivacyLevel: .show
-)
-SessionReplay.enable(with: sessionReplayConfig)
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
-
-
-
-
- -
-
-
import {
-  SessionReplay,
-  SessionReplayConfiguration,
-  TouchPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const config: SessionReplayConfiguration = {
-  replaySampleRate: sampleRate,
-  touchPrivacyLevel: TouchPrivacyLevel.SHOW,
-}
-
-SessionReplay.enable(config)
-
-
-
-
-
-

- Bundled images are those that use AssetImage as their image - provider. -

-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-    // ...
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        touchPrivacyLevel: TouchPrivacyLevel.show,
-        replaySampleRate: replay,
-    ),
-);
-
-
-
-
-
-
-

Privacy overrides

-

- The sections above describe the global masking levels that apply to the - entire application. However, it is also possible to override these settings - at the view level. The same privacy levels as above are available for text - and inputs, images, touches, and an additional setting to completely hide a - specific view. -

-

- To ensure overrides are recognized properly, they should be applied as early - as possible in the view lifecycle. This prevents scenarios where Session - Replay might process a view before applying the overrides. -

-

- Privacy overrides affect views and their descendants. This means that even - if an override is applied to a view where it might have no immediate effect - (for example, applying an image override to a text input), the override - still applies to all child views. -

-

- Overrides operate using a "nearest parent" principle: if a view - has an override, it uses that setting. Otherwise, it inherits the privacy - level from the closest parent in the hierarchy with an override. If no - parent has an override, the view defaults to the application's general - masking level. -

-
-

Text and input override

-
-

- To override text and input privacy in Android classic view, use - setSessionReplayTextAndInputPrivacy on a view instance and - pass a value from the TextAndInputPrivacy enum. Passing - null removes the override. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a text and input override on your view
-myView.setSessionReplayTextAndInputPrivacy(TextAndInputPrivacy.MASK_SENSITIVE_INPUTS)
-// Remove a text and input override from your view
-myView.setSessionReplayTextAndInputPrivacy(null)
-
-
-
-
-

- To override text and input privacy in Jetpack Compose, use - Modifier.sessionReplayTextAndInputPrivacy on the modifier - of a composable and pass a value from the - TextAndInputPrivacy enum. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a text and input override on your view
-Text(modifier = Modifier
-    .padding(16.dp)
-    .sessionReplayTextAndInputPrivacy(textAndInputPrivacy = TextAndInputPrivacy.MASK_SENSITIVE_INPUTS),
-  text = "Datadog"
-)
-
-
-
-
-
-
-

- To override text and input privacy in UIKit views, use - dd.sessionReplayOverrides.textAndInputPrivacy on a view - instance and set a value from the - TextAndInputPrivacyLevel enum. Setting it to - nil removes the override. -

-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
// Set a text and input override on your view
-myView.dd.sessionReplayOverrides.textAndInputPrivacy = .maskSensitiveInputs
-// Remove a text and input override from your view
-myView.dd.sessionReplayOverrides.textAndInputPrivacy = nil
-
-
-
-
-

- To override text and input privacy in SwiftUI, wrap your content with - SessionReplayPrivacyView and configure the - textAndInputPrivacy parameter. You can combine this with - other privacy settings in the same view for better performance. -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct ContentView: View {
-    @State private var username = ""
-    @State private var password = ""
-
-    var body: some View {
-        // Set a text and input override on your SwiftUI content
-        SessionReplayPrivacyView(textAndInputPrivacy: .maskAllInputs) {
-            VStack {
-                Text("User Profile")
-                TextField("Enter name", text: $username)
-                SecureField("Password", text: $password)
-            }
-        }
-    }
-}
-
-
-
-
-
-
-

- To override text and input privacy in Flutter, use the - SessionReplayPrivacy widget to override the privacy - settings for an entire widget tree. Setting any value to - null keeps the privacy values unchanged from values - provided higher up the widget tree. -

-
-
-
-
-
-
-
-
-
- -
-
-
class MyWidget: StatelessWidget {
-  Widget build() {
-    return SessionReplayPrivacy(
-      textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskAllInputs,
-      child: TextField(
-        decoration: InputDecoration(
-          labelText: 'Simple Text Field',
-        ),
-      ),
-    );
-  }
-}
-
-
-
-
-
-

Image override

-
-

- To override image privacy in Android classic view, use - setSessionReplayImagePrivacy on a view instance and pass a - value from the ImagePrivacy enum. Passing - null removes the override. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set an image override on your view
-myView.setSessionReplayImagePrivacy(ImagePrivacy.MASK_ALL)
-// Remove an image override from your view
-myView.setSessionReplayImagePrivacy(null)
-
-
-
-
-

- To override image privacy in Jetpack Compose, use - Modifier.sessionReplayImagePrivacy on the modifier of a - composable and pass a value from the ImagePrivacy enum. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a image privacy override on your image
-Image(modifier = Modifier
-  .padding(16.dp)
-  .sessionReplayImagePrivacy(imagePrivacy = ImagePrivacy.MASK_ALL),
-  painter = painterResource(id = R.drawable.ic_datadog),
-  contentDescription = null
-)
-
-
-
-
-
-
-

- To override image privacy in UIKit views, use - dd.sessionReplayOverrides.imagePrivacy on a view instance - and set a value from the ImagePrivacyLevel enum. Setting it - to nil removes the override. -

-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
// Set an image override on your view
-myView.dd.sessionReplayOverrides.imagePrivacy = .maskAll
-// Remove an image override from your view
-myView.dd.sessionReplayOverrides.imagePrivacy = nil
-
-
-
-
-

- To override image privacy in SwiftUI, wrap your content with - SessionReplayPrivacyView and configure the - imagePrivacy parameter. -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct ProfileView: View {
-    let profileImageURL = URL(string: "https://example.com/profile.jpg")
-
-    var body: some View {
-        // Set an image privacy override on your SwiftUI content
-        SessionReplayPrivacyView(imagePrivacy: .maskAll) {
-            VStack {
-                Image("userAvatar")
-                    .resizable()
-                    .frame(width: 60, height: 60)
-                    .clipShape(Circle())
-
-                AsyncImage(url: profileImageURL) { image in
-                    image.resizable()
-                } placeholder: {
-                    ProgressView()
-                }
-                .frame(width: 100, height: 100)
-            }
-        }
-    }
-}
-
-
-
-
-
-
-

- To override image privacy in Flutter, use the - SessionReplayPrivacy widget to override the privacy - settings for an entire widget tree. Setting any value to - null keeps the privacy values unchanged from values - provided higher up the widget tree. -

-
-
-
-
-
-
-
-
-
- -
-
-
class MyWidget: StatelessWidget {
-  Widget build() {
-    return SessionReplayPrivacy(
-      imagePrivacyLevel: ImagePrivacyLevel.maskAll,
-      child: Image.asset('assets/my_image.png'),
-    );
-  }
-}
-
-
-
-
-
-

Touch override

-
-

- To override touch privacy in Android classic view, use - setSessionReplayTouchPrivacy on a view instance and pass a - value from the TouchPrivacy enum. Passing - null removes the override. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a touch override on your view
-view.setSessionReplayTouchPrivacy(TouchPrivacy.HIDE)
-// Remove a touch override from your view
-view.setSessionReplayTouchPrivacy(null)
-
-
-
-
-

- To override touch privacy in Jetpack Compose, use - Modifier.sessionReplayTouchPrivacy on the modifier of a - composable and pass a value from the TouchPrivacy enum. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Set a touch privacy override on your view
-Column(modifier = Modifier
-  .padding(16.dp)
-  .sessionReplayTouchPrivacy(touchPrivacy = TouchPrivacy.HIDE)){
-  // Content
-}
-
-
-
-
-
-
-

- To override touch privacy in UIKit views, use - dd.sessionReplayOverrides.touchPrivacy on a view instance - and set a value from the TouchPrivacyLevel enum. Setting it - to nil removes the override. -

-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
// Set a touch override on your view
-myView.dd.sessionReplayOverrides.touchPrivacy = .hide
-// Remove a touch override from your view
-myView.dd.sessionReplayOverrides.touchPrivacy = nil
-
-
-
-
-

- To override touch privacy in SwiftUI, wrap your content with - SessionReplayPrivacyView and configure the - touchPrivacy parameter. -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct SettingsView: View {
-    @State private var sliderValue = 0.5
-
-    var body: some View {
-        // Set a touch privacy override on your SwiftUI content
-        SessionReplayPrivacyView(touchPrivacy: .hide) {
-            VStack(spacing: 20) {
-                Button("Some Action") {
-                    // Handle action
-                }
-                .padding()
-                .background(Color.blue)
-                .foregroundColor(.white)
-                .cornerRadius(8)
-
-                Slider(value: $sliderValue, in: 0...1) {
-                    Text("Some Value")
-                }
-            }
-            .padding()
-        }
-    }
-}
-
-
-
-
-
-
-

- To override touch privacy in Flutter, use the - SessionReplayPrivacy widget to override the privacy - settings for an entire widget tree. Setting any value to - null keeps the privacy values unchanged from values - provided higher up the widget tree. -

-

- Enabling touch privacy affects the entire widget tree, and cannot be - toggled back to "show" in children. -

-
-
-
-
-
-
-
-
-
- -
-
-
class MyWidget: StatelessWidget {
-  Widget build() {
-    return SessionReplayPrivacy(
-      touchPrivacyLevel: TouchPrivacyLevel.hide,
-      child: PinPadWidget(),
-    );
-  }
-}
-
-
-
-
-
-

Hidden elements override

-

- For sensitive elements that need to be completely hidden, use the - hidden setting. -

-

- When an element is hidden, it is replaced by a placeholder - labeled as "Hidden" in the replay, and its subviews are not - recorded. -

-

- Note: Marking a view as hidden does not - prevent touch interactions from being recorded on that element. To hide - touch interactions as well, use the - touch override in addition to marking the - element as hidden. -

-
-

- Use setSessionReplayHidden(hide = true) to hide the - element. Setting hide to false removes the - override. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Mark a view as hidden
-myView.setSessionReplayHidden(hide = true)
-// Remove the override from the view
-myView.setSessionReplayHidden(hide = false)
-
-
-
-
-

- Use Modifier.sessionReplayHide to hide the element in - Jetpack Compose. -

-
-
-

application.kt

-
-
-
-
-
-
-
- -
-
-
// Mark a Column as hidden
-Column(modifier = Modifier
-  .padding(16.dp)
-  .sessionReplayHide(hide = true)){
-  // Content
-}
-
-
-
-
-
-
-

- In UIKit views, use dd.sessionReplayOverrides.hide to hide - the element: -

-
-
-

AppDelegate.swift

-
-
-
-
-
-
-
- -
-
-
// Mark a view as hidden
-myView.dd.sessionReplayOverrides.hide = true
-// Remove the override from the view
-myView.dd.sessionReplayOverrides.hide = false
-
-
-
-
-

- In SwiftUI, wrap your content with - SessionReplayPrivacyView and set the - hide parameter to true: -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct PaymentView: View {
-    @State private var cardNumber = ""
-    @State private var cvv = ""
-
-    var body: some View {
-        // Mark SwiftUI content as hidden
-        SessionReplayPrivacyView(hide: true) {
-            VStack(spacing: 16) {
-                Text("Payment Information")
-                    .font(.headline)
-
-                TextField("Card Number", text: $cardNumber)
-                    .textFieldStyle(RoundedBorderTextFieldStyle())
-
-                SecureField("CVV", text: $cvv)
-                    .textFieldStyle(RoundedBorderTextFieldStyle())
-
-                Text("Card ending in 1234")
-                    .foregroundColor(.secondary)
-            }
-            .padding()
-        }
-    }
-}
-
-
-
-
-

- Note: Setting the hidden override to - nil or false has the same effect—it disables - the override. -

-

- Combining privacy settings in SwiftUI -

-

- Combine multiple privacy settings in one - SessionReplayPrivacyView for different configurations. - Datadog recommends - combining options in a single view rather than nesting multiple - instances - to avoid adding unnecessary view layers. -

-
-
-

ContentView.swift

-
-
-
-
-
-
-
- -
-
-
struct UserProfileView: View {
-    @State private var userBio = ""
-    @State private var cardNumber = ""
-
-    var body: some View {
-        VStack(spacing: 30) {
-            // Preferred: Combine multiple privacy settings in one view
-            SessionReplayPrivacyView(
-                textAndInputPrivacy: .maskSensitiveInputs,
-                imagePrivacy: .maskNonBundledOnly,
-                touchPrivacy: .show
-            ) {
-                VStack(spacing: 20) {
-                    // User profile section
-                    HStack {
-                        AsyncImage(url: URL(string: "https://example.com/profile.jpg")) { image in
-                            image.resizable()
-                        } placeholder: {
-                            Circle().fill(Color.gray.opacity(0.3))
-                        }
-                        .frame(width: 60, height: 60)
-                        .clipShape(Circle())
-
-                        VStack(alignment: .leading) {
-                            Text("John Doe")
-                                .font(.headline)
-                            TextField("Enter bio", text: $userBio)
-                                .textFieldStyle(RoundedBorderTextFieldStyle())
-                        }
-                    }
-
-                    Button("Save Profile") {
-                        // Save action
-                        print("Profile saved")
-                    }
-                    .padding()
-                    .background(Color.blue)
-                    .foregroundColor(.white)
-                    .cornerRadius(8)
-                }
-                .padding()
-            }
-
-            // For completely different privacy requirements, use separate `SessionReplayPrivacyView` instances
-            SessionReplayPrivacyView(hide: true) {
-                VStack(spacing: 16) {
-                    Text("Credit Card Information")
-                        .font(.headline)
-                    TextField("Card Number", text: $cardNumber)
-                        .textFieldStyle(RoundedBorderTextFieldStyle())
-                }
-                .padding()
-                .background(Color.gray.opacity(0.1))
-                .cornerRadius(8)
-            }
-        }
-        .padding()
-    }
-}
-
-
-
-
-

- Note: Each - SessionReplayPrivacyView introduces an additional native - view layer. For optimal performance, prefer combining privacy settings - instead of nesting multiple privacy views when possible. -

-
-
-

- To hide a widget tree in Flutter, use the - SessionReplayPrivacy widget to override the privacy - settings for an entire widget tree. -

-

- Hiding a widget tree affects the entire widget tree, and cannot be - toggled back to false in children, as Session Replay stops - processing widget trees that are marked with hide. -

-
-
-
-
-
-
-
-
-
- -
-
-
class MyWidget: StatelessWidget {
-  Widget build() {
-    return SessionReplayPrivacy(
-      hide: true,
-      child: PinPadWidget(),
-    );
-  }
-}
-
-
-
-
-
-
-
-

- Privacy overrides are fully supported in React Native starting from - version 2.8.0 of the Datadog - React Native SDK. Although the underlying functionality is shared with native Android and - iOS platforms, the integration in React Native is designed to align with - common React patterns. -

-

Behavior consistency

-

- React Native's implementation is built on the same foundation as the - native Android and iOS SDKs. As a result, you can rely on the privacy - features behaving the same way across all three platforms. -

-

Usage with SessionReplayView

-

- The SDK provides a set of React components under the - SessionReplayView namespace, which are used to configure - privacy settings within your React Native application. -

-

To use them, import SessionReplayView as follows:

-
-
-

App.tsx

-
-
-
- -
-
-
import { SessionReplayView } from "@datadog/mobile-react-native-session-replay";
-
-
-
-
-

This import provides access to four privacy-focused components.

-

- Each of these components behaves like a regular React Native View, meaning - they can be used anywhere you would typically use a View, with the - addition of privacy-related behavior. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ComponentDescriptionProperties
SessionReplayView.Privacy - Adds support for customizing text, image, and touch privacy settings - for its children. - - -
SessionReplayView.MaskAll - Applies the most restrictive privacy settings (MaskAll - or platform equivalent) to all children. - -
    -
  • showTouch?: boolean
  • -
-
SessionReplayView.MaskNone - Applies the least restrictive settings (MaskNone or - platform equivalent). All child components are visible. - (No additional properties)
SessionReplayView.HideCompletely hides all child components from session replay.(No additional properties)
-

Integration approaches

-

There are two ways to apply privacy overrides in React Native:

-
    -
  • - Wrap specific components with a privacy-focused - SessionReplayView to target only certain elements, or -
  • -
  • - Replace an entire <View> with a - SessionReplayView to apply privacy settings to a whole - section of your UI. -
  • -
-

- This flexibility lets you control which parts of your app are masked or - visible in session replays. -

-
- -
-
-

- Use SessionReplayView components to wrap specific parts - of your UI where you want to override privacy settings. -

-

For example, going from:

-
-
-

App.tsx

-
-
-
- -
-
-
const App = () => {
-  return (
-    <View>
-      {/* content */}
-      <TextInput placeholder="First Name" value="Data" />
-      <TextInput placeholder="Last Name" value="Dog" />
-      {/* content */}
-    </View>
-  );
-}
-
-
-
-
-

To:

-
-
-

App.tsx

-
-
-
- -
-
-
const App = () => {
-  return (
-    <View>
-      {/* content */}
-      <SessionReplayView.MaskAll showTouch={true}>
-      <TextInput placeholder="First Name" value="Data" />
-      <TextInput placeholder="Last Name" value="Dog" />
-      </SessionReplayView.MaskAll>
-      {/* content */}
-    </View>
-  );
-}
-
-
-
-
-
-
-

- Replace an existing <View> with a - SessionReplayView component directly. This is ideal - when a view already encapsulates the section of the UI that needs - modified privacy behavior. -

-

For example, instead of:

-
-
-

App.tsx

-
-
-
- -
-
-
const App = () => {
-  return (
-    <View>
-      {/* content */}
-    </View>
-  );
-}
-
-
-
-
-

You can use:

-
-
-

App.tsx

-
-
-
- -
-
-
const App = () => {
-  return (
-    <SessionReplayView.MaskNone>
-      {/* content */}
-    </SessionReplayView.MaskNone>
-  );
-}
-
-
-
-
-
-
-
-

Combining privacy components

-

- You can freely combine the SessionReplayView components to - apply different privacy settings to distinct sections of your UI. This is - especially useful when you need a mix of hidden elements, masked input - fields, and visible content within the same screen. -

-

For example:

-
-
-

App.tsx

-
-
-
- -
-
-
import { ImagePrivacyLevel, SessionReplayView, TextAndInputPrivacyLevel, TouchPrivacyLevel } from "@datadog/mobile-react-native-session-replay";
-
-const App = () => {
-  return (
-    <SessionReplayView.Privacy
-      textAndInputPrivacy={TextAndInputPrivacyLevel.MASK_SENSITIVE_INPUTS}
-      imagePrivacy={ImagePrivacyLevel.MASK_NONE}
-      touchPrivacy={TouchPrivacyLevel.SHOW}>
-      {/* content */}
-      <SessionReplayView.MaskAll showTouch={true}>
-        {/* content */}
-        <SessionReplayView.MaskNone>
-          {/* content */}
-        </SessionReplayView.MaskNone>
-        {/* content */}
-      </SessionReplayView.MaskAll>
-        {/* content */}
-      <SessionReplayView.Hide>
-        {/* content */}
-      </SessionReplayView.Hide>
-    </SessionReplayView.Privacy>
-  );
-}
-
-
-
-
-
-

Notes on WebViews

- -

How and what data is masked

-

- This section describes how the Datadog recorder handles masking based on - data type and how that data is defined. -

-

Text masking strategies

-

- Depending on how you've configured your privacy settings, the type of text, - and sensitivity of data, Datadog's masking rules apply different strategies - to different types of text fields. -

- - - - - - - - - - - - - - - - - - - - - - - - - -
Text masking strategyDescriptionExample
No maskThe text is revealed in the session replay - "Hello world" → - "Hello world" -
Space-preserving mask - Each visible character is replaced with a lowercase "x" - - "Hello world" → - "xxxxx xxxxx" -
Fixed-length mask - The entire text field is replaced with a constant of three asterisks - (***) - - "Hello world""***" -
-

- With the above text strategies in mind, you have a few different options if - you want to override the default privacy rule of mask in your - configuration. -

-

- The following chart shows how Datadog applies different text masking - strategies, using the rules you set up in your configuration, to the below - text types. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeAllow allMask allMask user input
Sensitive textFixed-length maskFixed-length maskFixed-length mask
Input and option textNo maskFixed-length maskFixed-length mask
Static textNo maskSpace-preserving maskNo mask
Hint textNo maskFixed-length maskNo mask
-

Text masking definitions

-

- Find below a description of how Datadog's recorder treats each text type. -

-

Sensitive text

-

- Sensitive text includes passwords, e-mails, and phone numbers marked in a - platform-specific way, and other forms of sensitivity in text available to - each platform. -

-
-

Sensitive text can be detected in:

-
    -
  • Edit Text
  • -
  • Address information
  • -
-
-
-

Sensitive text can be detected in:

-
    -
  • Text Field
  • -
  • Text View
  • -
  • Address information
  • -
  • Credit card numbers
  • -
  • One-time codes
  • -
-
-
-

Sensitive text can be detected in the following components.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ComponentPlatform(s)
Text FieldiOS
Text ViewiOS
Edit TextAndroid
Address informationiOS, Android
Credit card numbersiOS
One-time codesiOS
-
- - - - - - - - - - - - -
TextInputType.nameTextInputType.phoneTextInputType.emailAddressTextInputType.streetAddressTextInputType.twitterTextInputType.visiblePassword
-

Input and option text

-

- Input and option text is text entered by the user with a keyboard or other - text-input device, or a custom (non-generic) value in selection elements. -

-

This includes the below.

-
-
    -
  • - User-entered text in: -
      -
    • Text Field
    • -
    • Text View
    • -
    -
  • -
  • - User-selected options in: -
      -
    • Value Picker
    • -
    • Segment
    • -
    -
  • -
  • - Notable exclusions: -
      -
    • - Placeholder (hint) texts in Text Field and Text View (not entered by - the user) -
    • -
    • Non-editable texts in Text View
    • -
    • Month, day, and year labels in Date Picker (generic values)
    • -
    -
  • -
-
-
-
    -
  • - User-entered text in: -
      -
    • Edit Text
    • -
    -
  • -
  • - User-selected options in: -
      -
    • Value Picker
    • -
    • Drop Down List
    • -
    -
  • -
  • - Notable exclusions: -
      -
    • - Placeholder (hint) texts in Edit Text (not entered by the user) -
    • -
    • Month, day, and year labels in Date Picker (generic values)
    • -
    -
  • -
-
-
-
    -
  • - User-entered text in: -
      -
    • Text Field (iOS)
    • -
    • Text View (iOS)
    • -
    • Edit Text (Android)
    • -
    -
  • -
  • - User-selected options in: -
      -
    • Value Picker (iOS + Android)
    • -
    • Segment (iOS)
    • -
    • Drop Down List (Android)
    • -
    -
  • -
  • - Notable exclusions: -
      -
    • - Placeholder (hint) texts in Text Field, Text View and Edit Text (not - entered by the user) -
    • -
    • Non-editable texts in Text View (iOS).
    • -
    • Month, day, and year labels in Date Picker (generic values)
    • -
    -
  • -
-
-
-
    -
  • - User-entered text in EditableText, which is used in: -
      -
    • TextField
    • -
    • CupertinoTextField
    • -
    • many custom TextField implementations
    • -
    -
  • -
  • - Notable exclusions: -
      -
    • - Placeholder (hint) texts in Text Field and Text View (not entered by - the user) -
    • -
    • Text in Text Decorations (not entered by the user)
    • -
    • Month, day, and year labels in Date Picker (generic values)
    • -
    -
  • -
-
-

Static text

-

- Static text is any text that is not directly entered by the user. This - includes the below. -

-

All texts in:

-
-
    -
  • Texts in non-editable Text View
  • -
  • Month, day, and year labels in the date and time picker
  • -
  • - Values updated in response to gesture interaction with input elements, - such as the current value of the Slider -
  • -
  • - Other controls, not considered as "user input elements", such - as Labels, Tab Bar, and Navigation Bar -
  • -
-
-
-
    -
  • Checkbox and Radio Button titles
  • -
  • Month, day, and year labels in the date and time picker
  • -
  • - Values updated in response to gesture interaction with input elements, - such as the current value of the Slider -
  • -
  • - Other controls, not considered as "user input elements", such - as Tabs -
  • -
-
-
-
    -
  • Checkbox and Radio Button titles (Android)
  • -
  • Texts in non-editable Text View (iOS)
  • -
  • Month, day and year labels in the date and time picker
  • -
  • - Values updated in response to gesture interaction with input elements, - such as the current value of the Slider -
  • -
  • - Other controls, not considered as "user input elements", such - as Labels, Tab Bar, and Navigation Bar (iOS), or Tabs (Android) -
  • -
-
-
-
    -
  • Checkbox and Radio Button titles
  • -
  • Month, day and year labels in the date and time picker
  • -
  • - Values updated in response to gesture interaction with input elements, - such as the current value of the Slider -
  • -
  • - Other controls, not considered as "user input elements", such - as Text, Tab Bar, and Bottom Navigation Bar -
  • -
-
-

Hint text

-

- Hint text is static text in editable text elements or option selectors that - is displayed when no value is given. This includes: -

-
-
    -
  • Placeholders in Text Field
  • -
  • Placeholders in Text View
  • -
-
-
-
    -
  • Hints in Edit Text
  • -
  • Prompts in Drop Down lists
  • -
-
-
-
    -
  • Placeholders in Text Field (iOS), Text View (iOS)
  • -
  • Hints in Edit Text (Android)
  • -
  • Prompts in Drop Down lists (Android)
  • -
-
-
-
    -
  • InputDecoration elements in TextView
  • -
  • Placeholder text in CupertinoTextField
  • -
-
-

Appearance masking

-

- The following chart shows how we apply different appearance masking - strategies, using the rules you set up in your configuration, to the below - text types. -

- - - - - - - - - - - - - - - - - - - - - - - -
TypeAllow allMask allMask user input
Revealing attributes
Other attributes
-

Revealing attributes

-

- Revealing attributes are attributes that can reveal or suggest the value of - input elements and can be used to infer a user's input or selection. -

-

This includes:

-
-

Shapes

-
    -
  • Background of selected option in Segment
  • -
  • Circle surrounding the selected date in a Date Picker
  • -
  • Thumb of a Slider
  • -
-

Text attributes

-
    -
  • The color of a label rendering the selected date in Date Picker
  • -
  • The position of the first and last option in Value Picker
  • -
-
-
-

Shapes

-
    -
  • Selection mark in Checkbox
  • -
  • Thumb of a Slider
  • -
-

Text attributes

-
    -
  • The position of the first and last option in Value Picker
  • -
-
-
-

Shapes

- - - - - - - - - - - - - - - - - - - - - - - - - -
TypePlatform(s)
Background of selected option in SegmentiOS
Circle surrounding the selected date in Date PickeriOS
Selection mark in CheckboxAndroid
Thumb of a SlideriOS, Android
-

Text attributes

- - - - - - - - - - - - - - - - - -
TypePlatform(s)
- The color of a label rendering the selected date in Date Picker - iOS
The position of the first and last option in Value PickeriOS, Android
-
-
-

Shapes

-
    -
  • Background of selected option in Segment
  • -
  • Circle surrounding the selected date in a Date Picker
  • -
  • Thumb of a Slider
  • -
-

Text attributes

-
    -
  • The color of a label rendering the selected date in Date Picker
  • -
  • The position of the first and last option in Value Picker
  • -
-
-

Touch interactions

-

- The following chart shows how we apply different touch interaction - strategies, using the rules you set up in your configuration, to the below - text types. While any interaction that happens on an on-screen keyboard is - masked, interactions with other elements are not masked. -

- - - - - - - - - - - - - - - - - - - - - - - -
TypeAllow allMask allMask user input
Other attributes
On-screen keyboard
-

Image masking

-

- The following chart shows how we apply different image masking strategies: -

- - - - - - - - - - - - - - - - - - - - - - - -
TypeMask None -
Mask Large Only
-
- Mask Non Bundled Only -
-
- Mark Large Only (Android) / Mask Non Bundled Only (iOS) -
-
Mask All
Content ImageShownMaskedMasked
System ImageShownShownMasked
-

Further reading

-
-
- -{{< img src="real_user_monitoring/session_replay/mobile/masking-mode-mask-all-2.png" style="display:none;" alt="" >}} -{{< img src="real_user_monitoring/session_replay/mobile/masking-image-mask-all.png" style="display:none;" alt="" >}} -{{< img src="real_user_monitoring/session_replay/mobile/masking-image-mask-large-only.png" style="display:none;" alt="" >}} -{{< img src="real_user_monitoring/session_replay/mobile/masking-image-mask-non-bundled-only.png" style="display:none;" alt="" >}} - diff --git a/content/en/real_user_monitoring/session_replay/mobile/setup_and_configuration.md b/content/en/real_user_monitoring/session_replay/mobile/setup_and_configuration.md deleted file mode 100644 index d8a6083b96f..00000000000 --- a/content/en/real_user_monitoring/session_replay/mobile/setup_and_configuration.md +++ /dev/null @@ -1,1246 +0,0 @@ ---- -title: Mobile Session Replay Setup and Configuration -description: Setting up and configuring Mobile Session Replay. -further_reading: - - link: /real_user_monitoring/session_replay/mobile - tag: Documentation - text: Mobile Session Replay - - link: /real_user_monitoring/session_replay/mobile/app_performance - tag: Documentation - text: How Mobile Session Replay Impacts App Performance - - link: /real_user_monitoring/session_replay/mobile/privacy_options - tag: Documentation - text: Mobile Session Replay Privacy Options - - link: /real_user_monitoring/session_replay/mobile/troubleshooting - tag: Documentation - text: Troubleshoot Mobile Session Replay - - link: /real_user_monitoring/session_replay - tag: Documentation - text: Session Replay - - link: /real_user_monitoring/application_monitoring/android/web_view_tracking - tag: Documentation - text: Web View Tracking ---- -

SDK


-

Setup

-
-

- All Session Replay SDK versions can be found in the - Maven Central Repository. -

-

To set up Mobile Session Replay for Android:

-

- Step 1 - Set up the Android RUM SDK -

-

- Make sure you've - set up and initialized the Datadog Android RUM SDK - with views instrumentation enabled. -

-

- Step 2 - Declare the Datadog Session Replay as a dependency -

-
-
-

build.gradle.kts

-
-
-
- -
-
-
implementation("com.datadoghq:dd-sdk-android-rum:[datadog_version]")
-implementation("com.datadoghq:dd-sdk-android-session-replay:[datadog_version]")
-// in case you need Material support
-implementation("com.datadoghq:dd-sdk-android-session-replay-material:[datadog_version]")
-// in case you need Jetpack Compose support
-implementation("com.datadoghq:dd-sdk-android-session-replay-compose:[datadog_version]")
-
-
-
-
-

Step 3 - Enable Session Replay

-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  // in case you need Material extension support
-  .addExtensionSupport(MaterialExtensionSupport())
-  // in case you need Jetpack Compose support
-  .addExtensionSupport(ComposeExtensionSupport())
-  .build()
-
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-
-
-

To set up Mobile Session Replay for iOS:

-

Step 1 - Set up the iOS RUM SDK

-

- Make sure you've - set up and initialized the Datadog iOS RUM SDK - with views instrumentation enabled. -

-

- Step 2 - Declare the Datadog Session Replay as a dependency -

-
- -
-
-

- Add DatadogSessionReplay library as a dependency to - your app target. -

-
-
-

- Add pod 'DatadogSessionReplay to your - Podfile. -

-
-
-

- Add DatadogSessionReplay.xcframework as a dependency to - your app target. -

-
-
-
-

Step 3 - Enable Session Replay

-
-
-

AppDelegate.swift

-
-
-
- -
-
-
import DatadogSessionReplay
-
-SessionReplay.enable(
-  with: SessionReplay.Configuration(
-    replaySampleRate: sampleRate,
-    // Enable the experimental SwiftUI recording
-    featureFlags: [.swiftui: true]
-  )
-)
-
-
-
-
-
-
-

- All Session Replay SDK versions can be found in the - Maven Central Repository. -

-

To set up Mobile Session Replay for Kotlin Multiplatform:

-

- Step 1 - Set up the Kotlin Multiplatform RUM SDK -

-

- Make sure you've - set up and initialized the Datadog Kotlin Multiplatform RUM SDK - with views instrumentation enabled. -

-

- Step 2 - Add the DatadogSessionReplay iOS library as a - link-only dependency -

-

- For instructions, see the - guide. -

-

- Step 3 - Declare Datadog Session Replay as a dependency -

-
-
-

build.gradle.kts

-
-
-
- -
-
-
kotlin {
-  sourceSets {
-    commonMain.dependencies {
-      implementation("com.datadoghq:dd-sdk-kotlin-multiplatform-rum:[datadog_version]")
-      implementation("com.datadoghq:dd-sdk-kotlin-multiplatform-session-replay:[datadog_version]")
-    }
-
-    // in case you need Material support on Android
-    androidMain.dependencies {
-      implementation("com.datadoghq:dd-sdk-android-session-replay-material:[datadog_version]")
-    }
-  }
-}
-
-
-
-
-

Step 4 - Enable Session Replay

-
-
-

Application.kt

-
-
-
- -
-
-
// in common source set
-val sessionReplayConfig = SessionReplayConfiguration.Builder([sampleRate])
-  .build()
-SessionReplay.enable(sessionReplayConfig)
-
-
-
-
-

- Step 5 - Set up Material support on Android (Optional) -

-

If your app uses Material on Android, add:

-
-
-
-
- -
-
-
SessionReplayConfiguration.Builder.addExtensionSupport(MaterialExtensionSupport())
-
-
-
-
-
-
-
-

- To enable Session Replay, you must use at least version - 2.0.4 of the Datadog - React Native SDK, and ensure that the Session Replay SDK version matches the React - Native SDK version you are using. -

-
-

- All Session Replay SDK versions can be found in the - npmjs repository. -

-

To set up Mobile Session Replay for React Native:

-

- Step 1 - Set up the React Native SDK -

-

- Make sure you've - set up and initialized the Datadog React Native SDK - with views instrumentation enabled. -

-

- Step 2 - Declare the React Native Session Replay as a dependency -

-

- Add the - @datadog/mobile-react-native-session-replay dependency, and - make sure it matches the - @datadog/mobile-react-native version, either through - npm - or - yarn. -

-
- -
-
-
-
-
-
- -
-
-
npm install @datadog/mobile-react-native-session-replay
-
-
-
-
-
-
-
-
-
-
- -
-
-
yarn add @datadog/mobile-react-native-session-replay
-
-
-
-
-
-
-
-

Step 3 - Enable Session Replay

-

- After the Datadog React Native SDK and Session Replay SDK dependencies are - imported, you can enable the feature when configuring the SDK. -

-
- -
-
-

If you use the DatadogProvider component:

-
-
-

App.tsx

-
-
-
- -
-
-
import { DatadogProvider, DatadogProviderConfiguration } from "@datadog/mobile-react-native";
-import {
-  ImagePrivacyLevel,
-  SessionReplay,
-  TextAndInputPrivacyLevel,
-  TouchPrivacyLevel,
-} from "@datadog/mobile-react-native-session-replay";
-
-const configuration = new DatadogProviderConfiguration(/* ... */)
-
-// Add this function as onInitialization prop to DatadogProvider
-const onSDKInitialized = async () => {
-  await SessionReplay.enable({
-    replaySampleRate: 100, // Session Replay will be available for all sessions already captured by the SDK
-    textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_SENSITIVE_INPUTS,
-    imagePrivacyLevel: ImagePrivacyLevel.MASK_NONE,
-    touchPrivacyLevel: TouchPrivacyLevel.SHOW,
-  });
-};
-
-const App = () => {
-  const navigationRef = React.useRef(null);
-  return (
-    <DatadogProvider configuration={configuration} onInitialization={onSDKInitialized}>
-      {/* App */}
-    </DatadogProvider>
-  );
-};
-
-export default App;
-
-
-
-
-
-
-

If you use the DdSdkReactNative.initialize method:

-
-
-

App.tsx

-
-
-
- -
-
-
import { DdSdkReactNative, DdSdkReactNativeConfiguration } from "@datadog/mobile-react-native";
-import { SessionReplay } from "@datadog/mobile-react-native-session-replay";
-
-const configuration = new DdSdkReactNativeConfiguration(/* ... */)
-
-DdSdkReactNative.initialize(configuration)
-  .then(() => SessionReplay.enable({
-    replaySampleRate: 100, // Session Replay will be available for all sessions already captured by the SDK
-    textAndInputPrivacyLevel: TextAndInputPrivacyLevel.MASK_SENSITIVE_INPUTS,
-    imagePrivacyLevel: ImagePrivacyLevel.MASK_NONE,
-    touchPrivacyLevel: TouchPrivacyLevel.SHOW,
-  }))
-  .catch((error) => { /* handle error */ });
-
-
-
-
-
-
-
-

- During this step, you can also configure multiple - privacy levels - that apply to Session Replays. -

-

- Step 4 - (iOS only) Update your iOS pods. -

-
-
-
-
- -
-
-
cd ios && pod install
-
-
-
-
-

Step 5 - Rebuild your app

-

Rebuild your iOS and Android apps

-
-
-
-

Datadog Session Replay for Flutter is currently in Preview.

-
-

- All Session Replay SDK versions can be found in - Pub. -

-

To set up Datadog Session Replay for Flutter:

-

- Step 1 - Set up the Flutter plugin -

-

- Make sure you have - set up and initialized the Datadog Flutter Plugin. -

-

- Step 2 - Add the package to your pubspec.yaml -

-
-
-

pubspec.yaml

-
-
-
- -
-
-
packages:
-  # other packages
-  datadog_session_replay: ^x.x.x
-
-
-
-
-

- Step 3 - Enable Session Replay in your DatadogConfiguration -

-
-
-
-
- -
-
-
import 'package:datadog_session_replay/datadog_session_replay.dart';
-
-// ....
-final configuration = DatadogConfiguration(
-    // Normal Datadog configuration
-    clientToken: 'client-token',
-    // RUM is required to use Datadog Session Replay
-    rumConfiguration: RumConfiguration(
-        applicationId: '<application-id'>
-    ),
-)..enableSessionReplay(
-    DatadogSessionReplayConfiguration(
-        // Setup default text, image, and touch privacy
-        textAndInputPrivacyLevel: TextAndInputPrivacyLevel.maskSensitiveInputs,
-        touchPrivacyLevel: TouchPrivacyLevel.show,
-        // Setup session replay sample rate.
-        replaySampleRate: 100.0,
-    ),
-);
-
-
-
-
-

- Step 4 - Add a SessionReplayCapture to the root of your Widget tree -

-

- Add a SessionReplayCapture widget to the root of your Widget tree, above - your MaterialApp or similar application widget. -

-
-
-
-
- -
-
-
class MyApp extends StatefulWidget {
-  const MyApp({super.key});
-
-  @override
-  State<MyApp> createState() => _MyAppState();
-}
-
-class _MyAppState extends State<MyApp> {
-  // Note a key is required for SessionReplayCapture
-  final captureKey = GlobalKey();
-
-  // Other App Configuration
-
-  @override
-  Widget build(BuildContext context) {
-    return SessionReplayCapture(
-      key: captureKey,
-      rum: DatadogSdk.instance.rum!,
-      sessionReplay: DatadogSessionReplay.instance!,
-      child: MaterialApp.router(color: color, routerConfig: router),
-    );
-  }
-}
-
-
-
-
-
-

Web view instrumentation

-

- You can record the entire user journey across both - web and native views - on iOS or Android and watch it in a single Session Replay. -

-

- The Session Replay is recorded through the Browser SDK, then the Mobile SDK - handles the batching and uploading of the webview recording. -

-
-

- To instrument your consolidated web and native Session Replay views for - Android: -

-
    -
  1. - Ensure you are using version - 2.8.0 - or higher of the Android SDK. -
  2. -
  3. - Enable - webview tracking - for your mobile application. -
  4. -
  5. - Enable - Session Replay - for your web application. -
  6. -
  7. - Enable Session Replay for your mobile application (see setup - instructions above). -
  8. -
-
-
-

- To instrument your consolidated web and native Session Replay views for - iOS: -

-
    -
  1. - Ensure you are using version - 2.13.0 - or higher of the iOS SDK. -
  2. -
  3. - Enable - webview tracking - for your mobile application. -
  4. -
  5. - Enable - Session Replay - for your web application. -
  6. -
  7. - Enable Session Replay for your mobile application (see setup - instructions above). -
  8. -
-
-
-

- To instrument your consolidated web and native Session Replay views for - Kotlin Multiplatform: -

-
    -
  1. - Enable - webview tracking - for your mobile application. -
  2. -
  3. - Enable - Session Replay - for your web application. -
  4. -
  5. - Enable Session Replay for your mobile application (see setup - instructions above). -
  6. -
-
-
-

- To instrument your consolidated web and native Session Replay views for - React Native: -

-
    -
  1. - Enable - webview tracking - for your React Native application. -
  2. -
  3. - Enable - Session Replay - for your web application. -
  4. -
  5. - Enable Session Replay for your mobile application (see setup - instructions above). -
  6. -
-

- Note: This feature is not compatible with React Native's - New Architecture - for Android. -

-
-
-

- Datadog Session Replay for Flutter does not currently support Web view - capture. -

-
-

Additional configuration

-

- Set the sample rate for recorded sessions to appear -

-

- The sample rate is an optional parameter in the Session Replay - configuration. It must be a number between 0.0 and 100.0, where 0 indicates - that no replays are recorded and 100 means that all sessions include a - replay. If the sample rate is not specified in the configuration, the - default value of 100 is applied. -

-

- This sample rate is applied in addition to the RUM sample rate. For example, - if RUM uses a sample rate of 80% and Session Replay uses a sample rate of - 20%, it means that out of all user sessions, 80% are included in RUM, and - within those sessions, only 20% have replays. -

-
-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder(<SAMPLE_RATE>)
-  ...
-  .build()
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
- -
-
-
var sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: <SAMPLE_RATE>
-)
-
-
-
-
-
-
-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder(<SAMPLE_RATE>)
-  ...
-  .build()
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
- -
-
-
import { SessionReplay } from "@datadog/mobile-react-native-session-replay";
-
-SessionReplay.enable({
-  replaySampleRate: <SAMPLE_RATE>
-});
-
-
-
-
-
-
-
-
-
-
- -
-
-
final configuration = DatadogConfiguration(
-  // ...
-)..enableSessionReplay(
-  DatadogSessionReplayConfiguration(
-    replaySampleRate: <SAMPLE_RATE>
-  )
-);
-
-
-
-
-
-

- Start or stop the recording manually -

-

- By default, Session Replay starts recording automatically. However, if you - prefer to manually start recording at a specific point in your application, - you can use the optional startRecordingImmediately parameter as - shown below, and later call SessionReplay.startRecording(). You - can also use SessionReplay.stopRecording() to stop the - recording anytime. -

-
-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder(<SAMPLE_RATE>)
-  .startRecordingImmediately(false)
-  .build()
-// Do something
-SessionReplay.startRecording()
-SessionReplay.stopRecording()
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
- -
-
-
let sessionReplayConfig = SessionReplay.Configuration(
-  replaySampleRate: <SAMPLE_RATE>,
-  startRecordingImmediately: false
-)
-
-// Do something
-SessionReplay.startRecording()
-SessionReplay.stopRecording()
-
-
-
-
-
-
-
-
-

Application.kt

-
-
-
- -
-
-
val sessionReplayConfig = SessionReplayConfiguration.Builder(<SAMPLE_RATE>)
-  .startRecordingImmediately(false)
-  .build()
-
-// Do something
-SessionReplay.startRecording()
-SessionReplay.stopRecording()
-
-
-
-
-
-
-
-
-

App.tsx

-
-
-
- -
-
-
import { SessionReplay } from "@datadog/mobile-react-native-session-replay";
-
-SessionReplay.enable({
-  replaySampleRate: sampleRate,
-  startRecordingImmediately: false
-});
-// Do something
-SessionReplay.startRecording();
-SessionReplay.stopRecording();
-
-
-
-
-
-
-

- Datadog Session Replay for Flutter does not currently support manual - recording. -

-
-

- Validate whether Session Replay data is being sent -

-

- To validate whether Session Replay data is being sent from the app, you can - enable debug option in Datadog SDK. -

-
-
-
-

Application.kt

-
-
-
- -
-
-
Datadog.setVerbosity(Log.DEBUG)
-
-
-
-
-
-
-
-
-

AppDelegate.swift

-
-
-
- -
-
-
Datadog.verbosityLevel = .debug
-
-
-
-
-

- If everything is fine, following logs should appear in the Xcode debug - console in about 30 seconds after launching the app: -

-
-
-

Xcode console

-
-
-
- -
-
-
[DATADOG SDK] 🐶 → 10:21:29.812 ⏳ (session-replay) Uploading batch...
-[DATADOG SDK] 🐶 → 10:21:30.442    → (session-replay) accepted, won't be retransmitted: [response code: 202 (accepted), request ID: BD445EA-...-8AFCD3F3D16]
-
-
-
-
-
-
-
-
-

Application.kt

-
-
-
- -
-
-
Datadog.setVerbosity(SdkLogVerbosity.DEBUG)
-
-
-
-
-
-
-

Set the verbosity to DEBUG when you initialize the SDK:

-
-
-

App.tsx

-
-
-
- -
-
-
import { SdkVerbosity } from "@datadog/mobile-react-native";
-
-...
-
-config.verbosity = SdkVerbosity.DEBUG;
-
-
-
-
-
-
-

- Set the SDKs verbosity to CoreLoggerLevel.debug before you - initialize the SDK: -

-
-
-
-
- -
-
-
DatadogSdk.instance.sdkVerbosity = CoreLoggerLevel.debug;
-
-
-
-
-
-

Privacy options

-

- See - Privacy Options. -

-

Further reading

-
-
\ No newline at end of file