From bef80077967e4de9cc46497eb1a2f318e816b71c Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Tue, 25 Nov 2025 15:11:28 -0800 Subject: [PATCH 01/15] add SR to nav and move index --- config/_default/menus/main.en.yaml | 7 ++ .../session_replay/_index.md | 65 ------------------- .../session_replay/_index.md | 1 + 3 files changed, 8 insertions(+), 65 deletions(-) delete mode 100644 content/en/product_analytics/session_replay/_index.md rename content/en/{real_user_monitoring => }/session_replay/_index.md (99%) diff --git a/config/_default/menus/main.en.yaml b/config/_default/menus/main.en.yaml index 55f2a2832ff..2503b1896af 100644 --- a/config/_default/menus/main.en.yaml +++ b/config/_default/menus/main.en.yaml @@ -8466,6 +8466,13 @@ menu: parent: product_analytics identifier: pa_troubleshooting weight: 9 + + - name: Session Replay + url: session_replay/ + pre: play-circle + identifier: session_replay + parent: digital_experience_heading + weight: 60000 - name: Account Management url: account_management/ pre: cog-2 diff --git a/content/en/product_analytics/session_replay/_index.md b/content/en/product_analytics/session_replay/_index.md deleted file mode 100644 index 2ca0e8aac38..00000000000 --- a/content/en/product_analytics/session_replay/_index.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Replaying User Activity -description: Learn about how to capture and visually replay your users' web browsing or mobile app experience with Session Replay. -aliases: -- /real_user_monitoring/guide/session-replay-getting-started/ -further_reading: -- link: 'https://www.datadoghq.com/blog/session-replay-datadog/' - tag: 'Blog' - text: 'Use Datadog Session Replay to view real-time user journeys' -- link: 'https://www.datadoghq.com/blog/reduce-customer-friction-funnel-analysis/' - tag: 'Blog' - text: 'Use funnel analysis to understand and optimize key user flows' -- link: 'https://www.datadoghq.com/blog/zendesk-session-replay-integration/' - tag: 'Blog' - text: 'Visually replay user-facing issues with Zendesk and Datadog Session Replay' -- link: '/integrations/content_security_policy_logs' - tag: 'Documentation' - text: 'Detect and aggregate CSP violations with Datadog' ---- - - -## Overview - -Session Replay expands your user experience monitoring by allowing you to capture and visually replay the web browsing or mobile app experience of your users. Combined with RUM performance data, Session Replay is beneficial for error identification, reproduction, and resolution, and provides insights into your application's usage patterns and design pitfalls. - -## Browser Session Replay - -Browser Session Replay expands your user experience monitoring by allowing you to capture and visually replay the web browsing experience of your users. Combined with RUM performance data, Session Replay is beneficial for error identification, reproduction, and resolution, and provides insights into your web application's usage patterns and design pitfalls. - -The RUM Browser SDK is [open source][1] and leverages the open source [rrweb][2] project. - -Learn more about the [Session Replay for Browsers][3]. - -## Mobile Session Replay - -Mobile Session Replay expands visibility into your mobile applications by visually replaying each user interaction, such as taps, swipes, and scrolls. It is available for native apps on both Android and iOS. Visually replaying user interactions on your applications makes it easier to reproduce crashes and errors, as well as understand the user journey for making UI improvements. - -Learn more about the [Session Replay for Mobile][4]. - -## Playback history - -You can see who has watched a given session replay by clicking the **watched** count displayed on the player page. This feature allows you to check whether someone you'd like to share the recording with has already watched it. - -{{< img src="real_user_monitoring/session_replay/session-replay-playback-history.png" alt="Check who has watched a session's recording" style="width:100%;" >}} - -The history includes only playbacks that occurred in the player page or in an embedded player, like in a [Notebook][5] or side panel. Included playbacks also generate an [Audit Trail][6] event. Thumbnail previews are not included in history. - -To view your own playback history, check out the [My Watch History][7] playlist. - -## Playlists - -You can create a playlist of Session Replays to organize them by any patterns you notice. Learn more about [Session Replay Playlists][8]. - -## Further Reading - -{{< partial name="whats-next/whats-next.html" >}} - -[1]: https://github.com/DataDog/browser-sdk -[2]: https://www.rrweb.io/ -[3]: /product_analytics/session_replay/browser/ -[4]: /product_analytics/session_replay/mobile/ -[5]: https://docs.datadoghq.com/notebooks/ -[6]: https://docs.datadoghq.com/account_management/audit_trail/ -[7]: https://app.datadoghq.com/rum/replay/playlists/my-watch-history -[8]: /product_analytics/session_replay/playlists \ No newline at end of file diff --git a/content/en/real_user_monitoring/session_replay/_index.md b/content/en/session_replay/_index.md similarity index 99% rename from content/en/real_user_monitoring/session_replay/_index.md rename to content/en/session_replay/_index.md index 6229bcbc1a6..ffac11a48b6 100644 --- a/content/en/real_user_monitoring/session_replay/_index.md +++ b/content/en/session_replay/_index.md @@ -3,6 +3,7 @@ title: Session Replay description: Learn about how to capture and visually replay your users' web browsing or mobile app experience with Session Replay. aliases: - /real_user_monitoring/guide/session-replay-getting-started/ +- /real_user_monitoring/session_replay/ further_reading: - link: 'https://www.datadoghq.com/blog/session-replay-datadog/' tag: 'Blog' From f7952aa5122ce6f1f8d05da64eaf42775419db90 Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Tue, 16 Dec 2025 14:46:48 -0800 Subject: [PATCH 02/15] all browser and mobile index --- config/_default/menus/main.en.yaml | 80 +++++-------- .../session_replay/browser/_index.md | 65 ----------- .../session_replay/browser/developer_tools.md | 10 -- .../session_replay/browser/privacy_options.md | 13 --- .../browser/setup_and_configuration.md | 20 ---- .../session_replay/browser/troubleshooting.md | 16 --- .../session_replay/browser/_index.md | 15 ++- .../session_replay/browser/developer_tools.md | 2 + .../session_replay/browser/privacy_options.md | 2 + .../browser/setup_and_configuration.md | 3 + .../session_replay/browser/troubleshooting.md | 2 + content/en/session_replay/mobile/_index.md | 109 ++++++++++++++++++ 12 files changed, 158 insertions(+), 179 deletions(-) delete mode 100644 content/en/product_analytics/session_replay/browser/_index.md delete mode 100644 content/en/product_analytics/session_replay/browser/developer_tools.md delete mode 100644 content/en/product_analytics/session_replay/browser/privacy_options.md delete mode 100644 content/en/product_analytics/session_replay/browser/setup_and_configuration.md delete mode 100644 content/en/product_analytics/session_replay/browser/troubleshooting.md rename content/en/{real_user_monitoring => }/session_replay/browser/_index.md (85%) rename content/en/{real_user_monitoring => }/session_replay/browser/developer_tools.md (95%) rename content/en/{real_user_monitoring => }/session_replay/browser/privacy_options.md (98%) rename content/en/{real_user_monitoring => }/session_replay/browser/setup_and_configuration.md (97%) rename content/en/{real_user_monitoring => }/session_replay/browser/troubleshooting.md (97%) create mode 100644 content/en/session_replay/mobile/_index.md diff --git a/config/_default/menus/main.en.yaml b/config/_default/menus/main.en.yaml index 30621523a62..4c29e65bbb6 100644 --- a/config/_default/menus/main.en.yaml +++ b/config/_default/menus/main.en.yaml @@ -8245,31 +8245,6 @@ menu: parent: rum_session_replay_mobile identifier: rum_session_replay_mobile_troubleshooting weight: 104 - - name: Browser - url: real_user_monitoring/session_replay/browser - parent: rum_session_replay - identifier: rum_session_replay_browser - weight: 502 - - name: Setup - url: real_user_monitoring/session_replay/browser/setup_and_configuration - parent: rum_session_replay_browser - identifier: rum_session_replay_browser_setup - weight: 101 - - name: Privacy Options - url: real_user_monitoring/session_replay/browser/privacy_options - parent: rum_session_replay_browser - identifier: rum_session_replay_privacy_options - weight: 102 - - name: Developer Tools - url: real_user_monitoring/session_replay/developer_tools - parent: rum_session_replay_browser - identifier: rum_session_replay_developer_tools - weight: 103 - - name: Troubleshooting - url: real_user_monitoring/session_replay/troubleshooting - parent: rum_session_replay_browser - identifier: rum_session_replay_troubleshooting - weight: 104 - name: Playlists url: real_user_monitoring/session_replay/playlists parent: rum_session_replay @@ -8526,31 +8501,6 @@ menu: parent: pa_session_replay_mobile identifier: pa_session_replay_mobile_troubleshooting weight: 104 - - name: Browser - url: product_analytics/session_replay/browser - parent: pa_session_replay - identifier: pa_session_replay_browser - weight: 303 - - name: Setup - url: product_analytics/session_replay/browser/setup_and_configuration - parent: pa_session_replay_browser - identifier: pa_session_replay_browser_setup - weight: 101 - - name: Privacy Options - url: product_analytics/session_replay/browser/privacy_options - parent: pa_session_replay_browser - identifier: pa_session_replay_browser_privacy_options - weight: 102 - - name: Developer Tools - url: product_analytics/session_replay/browser/developer_tools - parent: pa_session_replay_browser - identifier: pa_session_replay_browser_developer_tools - weight: 103 - - name: Troubleshooting - url: product_analytics/session_replay/browser/troubleshooting - parent: pa_session_replay_browser - identifier: pa_session_replay_browser_troubleshooting - weight: 104 - name: Segments url: product_analytics/segmentation/ parent: product_analytics @@ -8597,6 +8547,36 @@ menu: identifier: session_replay parent: digital_experience_heading weight: 60000 + - name: Browser + url: /session_replay/browser + parent: session_replay + identifier: session_replay_browser + weight: 1 + - name: Setup + url: /session_replay/browser/setup_and_configuration + parent: session_replay_browser + identifier: session_replay_browser_setup + weight: 101 + - name: Privacy Options + url: /session_replay/browser/privacy_options + parent: session_replay_browser + identifier: session_replay_browser_privacy_options + weight: 102 + - name: Developer Tools + url: /session_replay/browser/developer_tools + parent: session_replay_browser + identifier: session_replay_browser_developer_tools + weight: 103 + - name: Troubleshooting + url: /session_replay/browser/troubleshooting + parent: session_replay_browser + identifier: session_replay_browser_troubleshooting + weight: 104 + - name: Mobile + url: /session_replay/mobile + parent: session_replay + identifier: session_replay_mobile + weight: 2 - name: Account Management url: account_management/ pre: cog-2 diff --git a/content/en/product_analytics/session_replay/browser/_index.md b/content/en/product_analytics/session_replay/browser/_index.md deleted file mode 100644 index e3134389dea..00000000000 --- a/content/en/product_analytics/session_replay/browser/_index.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Browser Session Replay -description: Learn about how to capture and visually replay your users' web browsing experience with Session Replay. -further_reading: -- link: 'https://www.datadoghq.com/blog/session-replay-datadog/' - tag: 'Blog' - text: 'Use Datadog Session Replay to view real-time user journeys' -- link: 'https://www.datadoghq.com/blog/reduce-customer-friction-funnel-analysis/' - tag: 'Blog' - text: 'Use funnel analysis to understand and optimize key user flows' -- link: 'https://www.datadoghq.com/blog/zendesk-session-replay-integration/' - tag: 'Blog' - text: 'Visually replay user-facing issues with Zendesk and Datadog Session Replay' -- link: '/product_analytics/analytics_explorer' - tag: 'Documentation' - text: 'Visualize your Product Analytics data in the Analytics Explorer' -- link: '/integrations/content_security_policy_logs' - tag: 'Documentation' - text: 'Detect and aggregate CSP violations with Datadog' ---- - - -## Overview - -Session Replay expands your user experience monitoring by allowing you to capture and visually replay the web browsing experience of your users. Combined with RUM performance data, Session Replay is beneficial for error identification, reproduction, and resolution, and provides insights into your web application's usage patterns and design pitfalls. - -The RUM Browser SDK is [open source][1] and leverages the open source [rrweb][2] project. - -## How the Session Replay recorder works - -The Session Replay recorder is part of the RUM Browser SDK. The recorder takes a snapshot of the browser's DOM and CSS by tailing and recording events happening on a web page (such as DOM modification, mouse move, clicks, and input events) along with these events' timestamps. - -Datadog then rebuilds the web page and re-applies the recorded events at the appropriate time in the replay view. Session Replay follows the same 30 day retention policy as normal RUM sessions. - -The Session Replay recorder supports all browsers supported by the RUM Browser SDK. For more information, see the [Browser Support table][3]. - -To reduce Session Replay's network impact and ensure the Session Replay recorder has minimal overhead on your application's performance, Datadog compresses the data prior to sending it. Datadog also reduces the load on a browser's UI thread by delegating most of the CPU-intensive work (such as compression) to a dedicated web worker. The expected network bandwidth impact is less than 100kB/min. - -## Setup - -Learn how to [set up and configure Browser Session Replay][4]. - -## Privacy options - -See [Privacy Options][5]. - -## Troubleshooting - -Learn how to [troubleshoot Browser Session Replay][7]. - -## Mobile Session Replay - -Learn more about [Session Replay for Mobile][8]. - -## Further Reading - -{{< partial name="whats-next/whats-next.html" >}} - -[1]: https://github.com/DataDog/browser-sdk -[2]: https://www.rrweb.io/ -[3]: https://github.com/DataDog/browser-sdk/blob/main/packages/rum/BROWSER_SUPPORT.md -[4]: /product_analytics/session_replay/browser/setup_and_configuration -[5]: /product_analytics/session_replay/browser/privacy_options -[7]: /product_analytics/session_replay/browser/troubleshooting -[8]: /product_analytics/session_replay/mobile/ diff --git a/content/en/product_analytics/session_replay/browser/developer_tools.md b/content/en/product_analytics/session_replay/browser/developer_tools.md deleted file mode 100644 index 502cfce087d..00000000000 --- a/content/en/product_analytics/session_replay/browser/developer_tools.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Session Replay Browser Developer Tools -description: Describes the developer tools available in Session Replay -further_reading: - - link: '/product_analytics/session_replay/browser' - tag: Documentation - text: Browser Session Replay ---- - -{{< include-markdown "real_user_monitoring/session_replay/browser/developer_tools" >}} \ No newline at end of file diff --git a/content/en/product_analytics/session_replay/browser/privacy_options.md b/content/en/product_analytics/session_replay/browser/privacy_options.md deleted file mode 100644 index 372b916824f..00000000000 --- a/content/en/product_analytics/session_replay/browser/privacy_options.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Session Replay Browser Privacy Options -description: Describes privacy controls available in Session Replay and how to set privacy options -further_reading: - - link: '/product_analytics/session_replay' - tag: Documentation - text: Session Replay - - link: "https://www.datadoghq.com/blog/default-privacy-session-replay/" - tag: "Blog" - text: "Obfuscate user data with Session Replay default privacy settings" ---- - -{{< include-markdown "real_user_monitoring/session_replay/browser/privacy_options" >}} \ No newline at end of file diff --git a/content/en/product_analytics/session_replay/browser/setup_and_configuration.md b/content/en/product_analytics/session_replay/browser/setup_and_configuration.md deleted file mode 100644 index d06090f8d2c..00000000000 --- a/content/en/product_analytics/session_replay/browser/setup_and_configuration.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Browser Session Replay Setup and Configuration -description: Setting up and configuring Mobile Session Replay. -aliases: -further_reading: - - link: '/product_analytics/session_replay/browser' - tag: Documentation - text: Browser Session Replay - - link: '/product_analytics/session_replay/browser/privacy_options' - tag: Documentation - text: Browser Session Replay Privacy Options - - link: '/product_analytics/session_replay/browser/troubleshooting' - tag: Documentation - text: Troubleshoot Browser Session Replay - - link: '/product_analytics/session_replay' - tag: Documentation - text: Session Replay ---- - -{{< include-markdown "real_user_monitoring/session_replay/browser/setup_and_configuration" >}} diff --git a/content/en/product_analytics/session_replay/browser/troubleshooting.md b/content/en/product_analytics/session_replay/browser/troubleshooting.md deleted file mode 100644 index cb773e5e452..00000000000 --- a/content/en/product_analytics/session_replay/browser/troubleshooting.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Session Replay Browser Troubleshooting -description: Learn how to troubleshoot issues with Session Replay. -further_reading: -- link: 'https://github.com/DataDog/browser-sdk' - tag: "Source Code" - text: 'browser-sdk Source code' -- link: '/product_analytics/session_replay' - tag: 'Documentation' - text: 'Learn about Session Replay' -- link: '/integrations/content_security_policy_logs' - tag: 'Documentation' - text: 'Detect and aggregate CSP violations with Datadog' ---- - -{{< include-markdown "real_user_monitoring/session_replay/browser/troubleshooting" >}} \ No newline at end of file diff --git a/content/en/real_user_monitoring/session_replay/browser/_index.md b/content/en/session_replay/browser/_index.md similarity index 85% rename from content/en/real_user_monitoring/session_replay/browser/_index.md rename to content/en/session_replay/browser/_index.md index c1f95e4fdcf..bde4256d5df 100644 --- a/content/en/real_user_monitoring/session_replay/browser/_index.md +++ b/content/en/session_replay/browser/_index.md @@ -3,6 +3,8 @@ title: Browser Session Replay description: Learn about how to capture and visually replay your users' web browsing experience with Session Replay. aliases: - /real_user_monitoring/guide/session-replay-getting-started/ +- /real_user_monitoring/session_replay/browser/ +- /product_analytics/session_replay/browser further_reading: - link: 'https://www.datadoghq.com/blog/session-replay-datadog/' tag: 'Blog' @@ -16,6 +18,9 @@ further_reading: - link: '/real_user_monitoring/explorer' tag: 'Documentation' text: 'Visualize your RUM data in the Explorer' +- link: '/product_analytics/analytics_explorer' + tag: 'Documentation' + text: 'Visualize your Product Analytics data in the Analytics Explorer' - link: '/integrations/content_security_policy_logs' tag: 'Documentation' text: 'Detect and aggregate CSP violations with Datadog' @@ -33,7 +38,7 @@ The Session Replay recorder is part of the RUM Browser SDK. The recorder takes a Datadog then rebuilds the web page and re-applies the recorded events at the appropriate time in the replay view. -The Session Replay recorder supports all browsers supported by the RUM Browser SDK with the exception of IE11. For more information, see the [browser support table][3]. +The Session Replay recorder supports all browsers supported by the RUM Browser SDK. For more information, see the [browser support table][3]. To reduce Session Replay's network impact and ensure the Session Replay recorder has minimal overhead on your application's performance, Datadog compresses the data prior to sending it. Datadog also reduces the load on a browser's UI thread by delegating most of the CPU-intensive work (such as compression) to a dedicated web worker. The expected network bandwidth impact is less than 100kB/min. @@ -60,7 +65,7 @@ Learn more about [Session Replay for Mobile][8]. [1]: https://github.com/DataDog/browser-sdk [2]: https://www.rrweb.io/ [3]: https://github.com/DataDog/browser-sdk/blob/main/packages/rum/BROWSER_SUPPORT.md -[4]: /real_user_monitoring/session_replay/browser/setup_and_configuration -[5]: /real_user_monitoring/session_replay/browser/privacy_options -[7]: /real_user_monitoring/session_replay/browser/troubleshooting -[8]: /real_user_monitoring/session_replay/mobile/ +[4]: /session_replay/browser/setup_and_configuration +[5]: /session_replay/browser/privacy_options +[7]: /session_replay/browser/troubleshooting +[8]: /session_replay/mobile/ diff --git a/content/en/real_user_monitoring/session_replay/browser/developer_tools.md b/content/en/session_replay/browser/developer_tools.md similarity index 95% rename from content/en/real_user_monitoring/session_replay/browser/developer_tools.md rename to content/en/session_replay/browser/developer_tools.md index c98f9d48092..a39191deb97 100644 --- a/content/en/real_user_monitoring/session_replay/browser/developer_tools.md +++ b/content/en/session_replay/browser/developer_tools.md @@ -3,6 +3,8 @@ title: Session Replay Browser Developer Tools description: Describes the developer tools available in Session Replay aliases: - /real_user_monitoring/session_replay/developer_tools +- /real_user_monitoring/session_replay/browser/developer_tools +- /product_analytics/session_replay/browser/developer_tools further_reading: - link: '/real_user_monitoring/session_replay/browser' tag: Documentation diff --git a/content/en/real_user_monitoring/session_replay/browser/privacy_options.md b/content/en/session_replay/browser/privacy_options.md similarity index 98% rename from content/en/real_user_monitoring/session_replay/browser/privacy_options.md rename to content/en/session_replay/browser/privacy_options.md index af2a98006f4..63b73546315 100644 --- a/content/en/real_user_monitoring/session_replay/browser/privacy_options.md +++ b/content/en/session_replay/browser/privacy_options.md @@ -3,6 +3,8 @@ title: Session Replay Browser Privacy Options description: Describes privacy controls available in Session Replay and how to set privacy options aliases: - /real_user_monitoring/session_replay/privacy_options +- /real_user_monitoring/session_replay/browser/privacy_options +- /product_analytics/session_replay/browser/privacy_options further_reading: - link: '/real_user_monitoring/session_replay' tag: Documentation diff --git a/content/en/real_user_monitoring/session_replay/browser/setup_and_configuration.md b/content/en/session_replay/browser/setup_and_configuration.md similarity index 97% rename from content/en/real_user_monitoring/session_replay/browser/setup_and_configuration.md rename to content/en/session_replay/browser/setup_and_configuration.md index 4a76e91b5ae..f0afdb1ba94 100644 --- a/content/en/real_user_monitoring/session_replay/browser/setup_and_configuration.md +++ b/content/en/session_replay/browser/setup_and_configuration.md @@ -1,6 +1,9 @@ --- title: Browser Session Replay Setup and Configuration description: Capture and visually replay your users' web browsing experience with Session Replay. +aliases: +- /real_user_monitoring/session_replay/browser/setup_and_configuration +- /product_analytics/session_replay/browser/setup_and_configuration further_reading: - link: 'https://www.datadoghq.com/blog/session-replay-datadog/' tag: 'Blog' diff --git a/content/en/real_user_monitoring/session_replay/browser/troubleshooting.md b/content/en/session_replay/browser/troubleshooting.md similarity index 97% rename from content/en/real_user_monitoring/session_replay/browser/troubleshooting.md rename to content/en/session_replay/browser/troubleshooting.md index fc8084c06c3..197db423558 100644 --- a/content/en/real_user_monitoring/session_replay/browser/troubleshooting.md +++ b/content/en/session_replay/browser/troubleshooting.md @@ -3,6 +3,8 @@ title: Session Replay Browser Troubleshooting description: Learn how to troubleshoot issues with Session Replay. aliases: - /real_user_monitoring/session_replay/troubleshooting +- /real_user_monitoring/session_replay/browser/troubleshooting +- /product_analytics/session_replay/browser/troubleshooting further_reading: - link: 'https://github.com/DataDog/browser-sdk' tag: "Source Code" diff --git a/content/en/session_replay/mobile/_index.md b/content/en/session_replay/mobile/_index.md new file mode 100644 index 00000000000..6cc914d75ac --- /dev/null +++ b/content/en/session_replay/mobile/_index.md @@ -0,0 +1,109 @@ +--- +title: Mobile Session Replay +description: Setting up Session Replay for mobile devices. +aliases: + - /real_user_monitoring/session_replay/mobile/ + - /product_analytics/session_replay/mobile/ +further_reading: + - link: '/session_replay' + tag: Documentation + text: Session Replay +--- +## Overview + +Mobile Session Replay expands visibility into your mobile applications by visually replaying each user interaction, such as taps, swipes, and scrolls. It is available for native apps on both Android and iOS. Visually replaying user interactions on your applications makes it easier to reproduce crashes and errors, as well as understand the user journey for making UI improvements. + +{{< img src="real_user_monitoring/session_replay/mobile/mobile_replay.mp4" alt="An example of a Mobile Session Replay recording" video="true" style="width:60%;">}} + +## How the Session Replay recorder works + +The Session Replay recorder is built into the RUM Mobile SDK. Unlike web browsers, mobile apps don't use HTML or CSS. Instead, the recorder takes a "snapshot" of your app's screen by breaking it into simple rectangles called "wireframes." It then keeps track of changes by only updating the wireframes that have changed, making the process efficient and fast. + +### Wireframe concept + +A _wireframe_ is like a digital sticky note that marks a specific area of your app's screen, such as a button, image, or background. Each wireframe is a rectangle that helps the recorder keep track of what's on the screen. + +**Examples of wireframes:** +- A text label becomes a "text" wireframe, defined by its position and size. +- The app's background is a "shape" wireframe—a rectangle that covers the whole screen. +- Any container with a solid background is also a "shape" wireframe. +- Images or icons are "image" wireframes, which can include style details like transparency. +- Even complex elements, like a map with many parts, can be combined into a single "image" wireframe. + +### Recording algorithm + +The recorder scans your app's screen from the background to the front, looking for all the visible parts. It creates a wireframe for each one. For example, a screen with 78 different elements can be simplified into just 25 wireframes: + +{{< img src="real_user_monitoring/session_replay/mobile/how-it-works/recording-algorithm-3.png" alt="An example of how the Shopist app screen contains 78 native views, but is made up of 25 wireframes." style="width:70%;">}} + +Wireframes are recorded in the order they appear on the screen (from back to front) and are placed using exact screen positions. There's no complicated tree structure, just a simple, flat list of rectangles. + +### Rendering algorithm + +When you watch a replay, Datadog's player rebuilds the screen by drawing each wireframe in order. It uses the position and size of each rectangle to put everything in the right place. The first wireframe sets the screen size and orientation (portrait or landscape). + +Each new wireframe is drawn on top of the previous ones, like stacking transparent sheets. This lets the player show things like overlapping or semi-transparent elements correctly. + +For instance, the screenshot displayed above is reconstructed in 25 passes: + +| Iteration | 1 | 2 | 3 | +|-----------|---|---|---| +| Viewport | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-1-1.png" alt="An example of a 'shape' wireframe." style="width:100%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-2-1.png" alt="An example of an 'image' wireframe." style="width:100%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-3-1.png" alt="An example of a 'text' wireframe." style="width:100%;">}} | + +The first wireframe dictates the viewport size, enabling the Session Replay player to properly represent the device's screen size and orientation (landscape / portrait). + +| Iteration | 4 | 5-11 | 12-13 | +|-----------|---|---|---| +| Viewport | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-4-1.png" alt="An example of a 'shape', 'image', and 'text' wireframe." style="width:100%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-5-1.png" alt="An example of a 'shape' and 'image' wireframe." style="width:100%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-6-1.png" alt="An example of a 'shape' and 'image' wireframe." style="width:100%;">}} | + +Because wireframes are sorted in back-to-front order, the player redraws the existing portions of the frame, which is desirable because it supports several UI patterns (such as semi-transparent elements). + +| Iteration | 14-25 | Final result | +|-----------|-------|--------------| +| Viewport | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-7-1.png" alt="An example of a 'shape' and 'image' wireframe." style="width:60%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-final-1.png" alt="An example of a 'shape' and 'image' wireframe." style="width:60%;">}} | + +### Full and incremental snapshots + +A "full snapshot" is like taking a picture of the entire screen, with all its wireframes. But to save time and data, the recorder usually sends "incremental snapshots", which are updates that include only the wireframes that have changed. + +Each wireframe has a unique ID (like a name tag), so the recorder knows exactly which ones to update. For example: +- If a wireframe moves, only its new position and ID are sent. +- If a wireframe disappears, the update says which ID was removed. +- If only the content changes (like new text), the update includes the new content and the wireframe's ID. + +Below are examples showing how incremental snapshots only send updates for impacted wireframes. + +| Example | Description | +|---------|-------------| +| {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/incremental-snapshots-change-position.mp4" alt="A snapshot a wireframe position changing but the content and appearance is not altered." video="true" >}} | If a wireframe position changes, but its content and appearance aren't altered, the incremental snapshot only needs to include new positions for impacted wireframes and their `UUIDs`. This might correspond to a "slow scrolling" scenario or any other scenario where only a portion of the screen is moved. | +| {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/incremental-wireframe-disappears.mp4" alt="An example of a wireframe disappearing from the screen." video="true" >}} | If a wireframe disappears from the screen, an incremental snapshot may only include information on removed `UUIDs`. Alternatively, the snapshot could always include information about the remaining `UUIDs`. | +| {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/incremental-content-only.mp4" alt="An example of only the content of a wireframe changing." video="true" >}} | If only the content of a wireframe changes, an incremental update includes only the new content and the `UUID` of the altered wireframe. | + +In summary, the Session Replay recorder breaks your app's screen into simple rectangles called wireframes. It only tracks and sends updates for the parts that change, making replays efficient and accurate. + +## Setup + +Learn how to [set up and configure Mobile Session Replay][2]. +## Privacy options + +See [Privacy Options][3]. + +## How Mobile Session Replay impacts app performance + +See [how Mobile Session Replay impacts app performance][4]. + +## Troubleshooting + +Learn how to [troubleshoot Mobile Session Replay][5]. + +
For Session Replay, Datadog supports RUM for native iOS and Android mobile apps, but not for smart TVs or wearables.
+ +## Further reading + +{{< partial name="whats-next/whats-next.html" >}} + +[1]: /session_replay/browser/#how-it-works +[2]: /session_replay/mobile/setup_and_configuration +[3]: /session_replay/mobile/privacy_options +[4]: /session_replay/mobile/app_performance +[5]: /session_replay/mobile/troubleshooting \ No newline at end of file From c705306dc4ef91cf552bf7818434656f31e74e10 Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Fri, 19 Dec 2025 14:53:16 -0800 Subject: [PATCH 03/15] rest of mobile --- config/_default/menus/main.en.yaml | 80 +- content/.gitignore | 4 +- .../session_replay/mobile/_index.md | 42 - .../session_replay/mobile/app_performance.md | 23 - .../mobile/privacy_options.mdoc.md | 26 - .../mobile/setup_and_configuration.mdoc.md | 26 - .../session_replay/mobile/troubleshooting.md | 23 - .../session_replay/playlists.md | 10 - .../session_replay/mobile/_index.md | 107 - .../session_replay/mobile/app_performance.md | 32 +- .../session_replay/mobile/privacy_options.md | 3376 +++++++++++++++++ .../mobile/privacy_options.mdoc.md | 30 + .../mobile/setup_and_configuration.mdoc.md | 0 .../session_replay/mobile/troubleshooting.md | 10 +- .../session_replay/playlists.md | 6 +- data/partials/home.yaml | 4 + .../mobile/privacy_options.mdoc.md | 2 +- .../setup_and_configuration.mdoc.md | 8 +- 18 files changed, 3461 insertions(+), 348 deletions(-) delete mode 100644 content/en/product_analytics/session_replay/mobile/_index.md delete mode 100644 content/en/product_analytics/session_replay/mobile/app_performance.md delete mode 100644 content/en/product_analytics/session_replay/mobile/privacy_options.mdoc.md delete mode 100644 content/en/product_analytics/session_replay/mobile/setup_and_configuration.mdoc.md delete mode 100644 content/en/product_analytics/session_replay/mobile/troubleshooting.md delete mode 100644 content/en/product_analytics/session_replay/playlists.md delete mode 100644 content/en/real_user_monitoring/session_replay/mobile/_index.md rename content/en/{real_user_monitoring => }/session_replay/mobile/app_performance.md (80%) create mode 100644 content/en/session_replay/mobile/privacy_options.md create mode 100644 content/en/session_replay/mobile/privacy_options.mdoc.md rename content/en/{real_user_monitoring => }/session_replay/mobile/setup_and_configuration.mdoc.md (100%) rename content/en/{real_user_monitoring => }/session_replay/mobile/troubleshooting.md (90%) rename content/en/{real_user_monitoring => }/session_replay/playlists.md (96%) diff --git a/config/_default/menus/main.en.yaml b/config/_default/menus/main.en.yaml index 4c29e65bbb6..2a2d2b4ef3e 100644 --- a/config/_default/menus/main.en.yaml +++ b/config/_default/menus/main.en.yaml @@ -8220,36 +8220,6 @@ menu: parent: rum identifier: rum_session_replay weight: 5 - - name: Mobile - url: real_user_monitoring/session_replay/mobile - parent: rum_session_replay - identifier: rum_session_replay_mobile - weight: 501 - - name: Setup - url: real_user_monitoring/session_replay/mobile/setup_and_configuration - parent: rum_session_replay_mobile - identifier: rum_session_replay_mobile_setup - weight: 101 - - name: Privacy Options - url: real_user_monitoring/session_replay/mobile/privacy_options - parent: rum_session_replay_mobile - identifier: rum_session_replay_mobile_privacy - weight: 102 - - name: Impact on App Performance - url: real_user_monitoring/session_replay/mobile/app_performance - parent: rum_session_replay_mobile - identifier: rum_session_replay_mobile_app_performance - weight: 103 - - name: Troubleshooting - url: real_user_monitoring/session_replay/mobile/troubleshooting - parent: rum_session_replay_mobile - identifier: rum_session_replay_mobile_troubleshooting - weight: 104 - - name: Playlists - url: real_user_monitoring/session_replay/playlists - parent: rum_session_replay - identifier: rum_session_replay_playlists - weight: 503 - name: Heatmaps url: real_user_monitoring/session_replay/heatmaps parent: rum_session_replay @@ -8471,36 +8441,6 @@ menu: parent: pa_session_replay identifier: pa_heatmaps weight: 301 - - name: Playlists - url: product_analytics/session_replay/playlists - parent: pa_session_replay - identifier: pa_playlists - weight: 302 - - name: Mobile - url: product_analytics/session_replay/mobile - parent: pa_session_replay - identifier: pa_session_replay_mobile - weight: 302 - - name: Setup - url: product_analytics/session_replay/mobile/setup_and_configuration - parent: pa_session_replay_mobile - identifier: pa_session_replay_mobile_setup - weight: 101 - - name: Privacy Options - url: product_analytics/session_replay/mobile/privacy_options - parent: pa_session_replay_mobile - identifier: pa_session_replay_mobile_privacy - weight: 102 - - name: Impact on App Performance - url: product_analytics/session_replay/mobile/app_performance - parent: pa_session_replay_mobile - identifier: pa_session_replay_mobile_app_performance - weight: 103 - - name: Troubleshooting - url: product_analytics/session_replay/mobile/troubleshooting - parent: pa_session_replay_mobile - identifier: pa_session_replay_mobile_troubleshooting - weight: 104 - name: Segments url: product_analytics/segmentation/ parent: product_analytics @@ -8577,6 +8517,26 @@ menu: parent: session_replay identifier: session_replay_mobile weight: 2 + - name: Setup and Configuration + url: /session_replay/mobile/setup_and_configuration + parent: session_replay_mobile + identifier: session_replay_mobile_setup_and_configuration + weight: 101 + - name: Privacy Options + url: /session_replay/mobile/privacy_options + parent: session_replay_mobile + identifier: session_replay_mobile_privacy_options + weight: 102 + - name: Impact on App Performance + url: /session_replay/mobile/app_performance + parent: session_replay_mobile + identifier: session_replay_mobile_app_performance + weight: 103 + - name: Troubleshooting + url: /session_replay/mobile/troubleshooting + parent: session_replay_mobile + identifier: session_replay_mobile_troubleshooting + weight: 104 - name: Account Management url: account_management/ pre: cog-2 diff --git a/content/.gitignore b/content/.gitignore index d53b1529da4..6ce31381d46 100644 --- a/content/.gitignore +++ b/content/.gitignore @@ -5,9 +5,7 @@ # This file lists compiled Cdocs files to keep them out of version control. For more information, see the internal Cdocs documentation: https://datadoghq.atlassian.net/wiki/spaces/docs4docs/pages/4898063037/Cdocs+Build -/en/product_analytics/session_replay/mobile/privacy_options.md -/en/product_analytics/session_replay/mobile/setup_and_configuration.md /en/real_user_monitoring/guide/proxy-mobile-rum-data.md /en/real_user_monitoring/guide/proxy-rum-data.md /en/real_user_monitoring/session_replay/mobile/privacy_options.md -/en/real_user_monitoring/session_replay/mobile/setup_and_configuration.md \ No newline at end of file +/en/session_replay/mobile/setup_and_configuration.md \ No newline at end of file diff --git a/content/en/product_analytics/session_replay/mobile/_index.md b/content/en/product_analytics/session_replay/mobile/_index.md deleted file mode 100644 index ea793d2ad51..00000000000 --- a/content/en/product_analytics/session_replay/mobile/_index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Mobile Session Replay -description: Setting up Session Replay for mobile devices. -aliases: -further_reading: - - link: '/product_analytics/session_replay' - tag: Documentation - text: Session Replay ---- - -## Overview - -Mobile Session Replay expands visibility into your mobile applications by visually replaying each user interaction, such as taps, swipes, and scrolls. It is available for native apps on both Android and iOS. Visually replaying user interactions on your applications makes it easier to reproduce crashes and errors, as well as understand the user journey for making UI improvements. - -{{< img src="real_user_monitoring/session_replay/mobile/mobile_replay.mp4" alt="An example of a Mobile Session Replay recording" video="true" style="width:60%;">}} - -## Setup - -Learn how to [Setup and Configure Mobile Session Replay][1]. - -## Privacy options - -See [Privacy Options][2]. - -## How Mobile Session Replay impacts app performance - -See [How Mobile Session Replay Impacts App Performance][3]. - -## Troubleshooting - -Learn how to [Troubleshoot Mobile Session Replay][4]. - -
For Session Replay, Datadog supports RUM for native iOS and Android mobile apps, but it is not supported for smart TVs or wearables.
- -## Further reading - -{{< partial name="whats-next/whats-next.html" >}} - -[1]: /product_analytics/session_replay/mobile/setup_and_configuration -[2]: /product_analytics/session_replay/mobile/privacy_options -[3]: /product_analytics/session_replay/mobile/app_performance -[4]: /product_analytics/session_replay/mobile/troubleshooting diff --git a/content/en/product_analytics/session_replay/mobile/app_performance.md b/content/en/product_analytics/session_replay/mobile/app_performance.md deleted file mode 100644 index 424b6488d8d..00000000000 --- a/content/en/product_analytics/session_replay/mobile/app_performance.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: How Mobile Session Replay Impacts App Performance -description: Performance benchmarking for Mobile Session Replay. -aliases: -further_reading: - - link: '/product_analytics/session_replay/mobile' - tag: Documentation - text: Mobile Session Replay - - link: '/product_analytics/session_replay/mobile/privacy_options' - tag: Documentation - text: Mobile Session Replay Privacy Options - - link: '/product_analytics/session_replay/mobile/setup_and_configuration' - tag: Documentation - text: Setup and Configure Mobile Session Replay - - link: '/product_analytics/session_replay/mobile/troubleshooting' - tag: Documentation - text: Troubleshoot Mobile Session Replay - - link: '/product_analytics/session_replay' - tag: Documentation - text: Session Replay ---- - -{{< include-markdown "real_user_monitoring/session_replay/mobile/app_performance" >}} \ No newline at end of file diff --git a/content/en/product_analytics/session_replay/mobile/privacy_options.mdoc.md b/content/en/product_analytics/session_replay/mobile/privacy_options.mdoc.md deleted file mode 100644 index db9d3f18f44..00000000000 --- a/content/en/product_analytics/session_replay/mobile/privacy_options.mdoc.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Mobile Session Replay Privacy Options -description: Configure privacy options for Mobile Session Replay. -content_filters: - - trait_id: platform - option_group_id: rum_sdk_platform_options_v2 - label: "SDK" -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 ---- - -{% partial file="real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md" /%} \ No newline at end of file diff --git a/content/en/product_analytics/session_replay/mobile/setup_and_configuration.mdoc.md b/content/en/product_analytics/session_replay/mobile/setup_and_configuration.mdoc.md deleted file mode 100644 index e11960b06da..00000000000 --- a/content/en/product_analytics/session_replay/mobile/setup_and_configuration.mdoc.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Mobile Session Replay Setup and Configuration -description: Setting up and configuring Mobile Session Replay. -content_filters: - - trait_id: platform - option_group_id: rum_session_replay_sdk_options - label: "SDK" -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 ---- - -{% partial file="real_user_monitoring/session_replay/setup_and_configuration.mdoc.md" /%} diff --git a/content/en/product_analytics/session_replay/mobile/troubleshooting.md b/content/en/product_analytics/session_replay/mobile/troubleshooting.md deleted file mode 100644 index a04985f60c2..00000000000 --- a/content/en/product_analytics/session_replay/mobile/troubleshooting.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Troubleshooting Mobile Session Replay -description: How to troubleshoot Mobile Session Replay. -aliases: -further_reading: - - link: '/product_analytics/session_replay/mobile' - tag: Documentation - text: Mobile Session Replay - - link: '/product_analytics/session_replay/mobile/setup_and_configuration' - tag: Documentation - text: Setup and Configure 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' - tag: Documentation - text: Session Replay ---- - -{{< include-markdown "real_user_monitoring/session_replay/mobile/troubleshooting" >}} \ No newline at end of file diff --git a/content/en/product_analytics/session_replay/playlists.md b/content/en/product_analytics/session_replay/playlists.md deleted file mode 100644 index 38c55cbca0d..00000000000 --- a/content/en/product_analytics/session_replay/playlists.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Session Replay Playlists -description: Learn how to create and use Playlists for organizing Session Replays. -aliases: -further_reading: - - link: '/product_analytics/session_replay' - tag: Documentation - text: Session Replay ---- -{{< include-markdown "real_user_monitoring/session_replay/playlists" >}} \ No newline at end of file diff --git a/content/en/real_user_monitoring/session_replay/mobile/_index.md b/content/en/real_user_monitoring/session_replay/mobile/_index.md deleted file mode 100644 index 4f03e23e341..00000000000 --- a/content/en/real_user_monitoring/session_replay/mobile/_index.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: Mobile Session Replay -description: Setting up Session Replay for mobile devices. -aliases: -further_reading: - - link: '/real_user_monitoring/session_replay' - tag: Documentation - text: Session Replay ---- -## Overview - -Mobile Session Replay expands visibility into your mobile applications by visually replaying each user interaction, such as taps, swipes, and scrolls. It is available for native apps on both Android and iOS. Visually replaying user interactions on your applications makes it easier to reproduce crashes and errors, as well as understand the user journey for making UI improvements. - -{{< img src="real_user_monitoring/session_replay/mobile/mobile_replay.mp4" alt="An example of a Mobile Session Replay recording" video="true" style="width:60%;">}} - -## How the Session Replay recorder works - -The Session Replay recorder is built into the RUM Mobile SDK. Unlike web browsers, mobile apps don't use HTML or CSS. Instead, the recorder takes a "snapshot" of your app's screen by breaking it into simple rectangles called "wireframes." It then keeps track of changes by only updating the wireframes that have changed, making the process efficient and fast. - -### Wireframe concept - -A _wireframe_ is like a digital sticky note that marks a specific area of your app's screen, such as a button, image, or background. Each wireframe is a rectangle that helps the recorder keep track of what's on the screen. - -**Examples of wireframes:** -- A text label becomes a "text" wireframe, defined by its position and size. -- The app's background is a "shape" wireframe—a rectangle that covers the whole screen. -- Any container with a solid background is also a "shape" wireframe. -- Images or icons are "image" wireframes, which can include style details like transparency. -- Even complex elements, like a map with many parts, can be combined into a single "image" wireframe. - -### Recording algorithm - -The recorder scans your app's screen from the background to the front, looking for all the visible parts. It creates a wireframe for each one. For example, a screen with 78 different elements can be simplified into just 25 wireframes: - -{{< img src="real_user_monitoring/session_replay/mobile/how-it-works/recording-algorithm-3.png" alt="An example of how the Shopist app screen contains 78 native views, but is made up of 25 wireframes." style="width:70%;">}} - -Wireframes are recorded in the order they appear on the screen (from back to front) and are placed using exact screen positions. There's no complicated tree structure, just a simple, flat list of rectangles. - -### Rendering algorithm - -When you watch a replay, Datadog's player rebuilds the screen by drawing each wireframe in order. It uses the position and size of each rectangle to put everything in the right place. The first wireframe sets the screen size and orientation (portrait or landscape). - -Each new wireframe is drawn on top of the previous ones, like stacking transparent sheets. This lets the player show things like overlapping or semi-transparent elements correctly. - -For instance, the screenshot displayed above is reconstructed in 25 passes: - -| Iteration | 1 | 2 | 3 | -|-----------|---|---|---| -| Viewport | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-1-1.png" alt="An example of a 'shape' wireframe." style="width:100%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-2-1.png" alt="An example of an 'image' wireframe." style="width:100%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-3-1.png" alt="An example of a 'text' wireframe." style="width:100%;">}} | - -The first wireframe dictates the viewport size, enabling the Session Replay player to properly represent the device's screen size and orientation (landscape / portrait). - -| Iteration | 4 | 5-11 | 12-13 | -|-----------|---|---|---| -| Viewport | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-4-1.png" alt="An example of a 'shape', 'image', and 'text' wireframe." style="width:100%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-5-1.png" alt="An example of a 'shape' and 'image' wireframe." style="width:100%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-6-1.png" alt="An example of a 'shape' and 'image' wireframe." style="width:100%;">}} | - -Because wireframes are sorted in back-to-front order, the player redraws the existing portions of the frame, which is desirable because it supports several UI patterns (such as semi-transparent elements). - -| Iteration | 14-25 | Final result | -|-----------|-------|--------------| -| Viewport | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-7-1.png" alt="An example of a 'shape' and 'image' wireframe." style="width:60%;">}} | {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/iteration-final-1.png" alt="An example of a 'shape' and 'image' wireframe." style="width:60%;">}} | - -### Full and incremental snapshots - -A "full snapshot" is like taking a picture of the entire screen, with all its wireframes. But to save time and data, the recorder usually sends "incremental snapshots", which are updates that include only the wireframes that have changed. - -Each wireframe has a unique ID (like a name tag), so the recorder knows exactly which ones to update. For example: -- If a wireframe moves, only its new position and ID are sent. -- If a wireframe disappears, the update says which ID was removed. -- If only the content changes (like new text), the update includes the new content and the wireframe's ID. - -Below are examples showing how incremental snapshots only send updates for impacted wireframes. - -| Example | Description | -|---------|-------------| -| {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/incremental-snapshots-change-position.mp4" alt="A snapshot a wireframe position changing but the content and appearance is not altered." video="true" >}} | If a wireframe position changes, but its content and appearance aren't altered, the incremental snapshot only needs to include new positions for impacted wireframes and their `UUIDs`. This might correspond to a "slow scrolling" scenario or any other scenario where only a portion of the screen is moved. | -| {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/incremental-wireframe-disappears.mp4" alt="An example of a wireframe disappearing from the screen." video="true" >}} | If a wireframe disappears from the screen, an incremental snapshot may only include information on removed `UUIDs`. Alternatively, the snapshot could always include information about the remaining `UUIDs`. | -| {{< img src="real_user_monitoring/session_replay/mobile/how-it-works/incremental-content-only.mp4" alt="An example of only the content of a wireframe changing." video="true" >}} | If only the content of a wireframe changes, an incremental update includes only the new content and the `UUID` of the altered wireframe. | - -In summary, the Session Replay recorder breaks your app's screen into simple rectangles called wireframes. It only tracks and sends updates for the parts that change, making replays efficient and accurate. - -## Setup - -Learn how to [set up and configure Mobile Session Replay][2]. -## Privacy options - -See [Privacy Options][3]. - -## How Mobile Session Replay impacts app performance - -See [how Mobile Session Replay impacts app performance][4]. - -## Troubleshooting - -Learn how to [troubleshoot Mobile Session Replay][5]. - -
For Session Replay, Datadog supports RUM for native iOS and Android mobile apps, but not for smart TVs or wearables.
- -## Further reading - -{{< partial name="whats-next/whats-next.html" >}} - -[1]: /real_user_monitoring/session_replay/browser/#how-it-works -[2]: /real_user_monitoring/session_replay/mobile/setup_and_configuration -[3]: /real_user_monitoring/session_replay/mobile/privacy_options -[4]: /real_user_monitoring/session_replay/mobile/app_performance -[5]: /real_user_monitoring/session_replay/mobile/troubleshooting diff --git a/content/en/real_user_monitoring/session_replay/mobile/app_performance.md b/content/en/session_replay/mobile/app_performance.md similarity index 80% rename from content/en/real_user_monitoring/session_replay/mobile/app_performance.md rename to content/en/session_replay/mobile/app_performance.md index f4dc68f4d39..6d062b5cbf1 100644 --- a/content/en/real_user_monitoring/session_replay/mobile/app_performance.md +++ b/content/en/session_replay/mobile/app_performance.md @@ -2,22 +2,24 @@ title: How Mobile Session Replay Impacts App Performance description: Performance benchmarking for Mobile Session Replay. aliases: + - /real_user_monitoring/session_replay/mobile/app_performance + - /product_analytics/session_replay/mobile/app_performance further_reading: - - link: '/real_user_monitoring/session_replay/mobile' - tag: Documentation - text: Mobile Session Replay - - link: '/real_user_monitoring/session_replay/mobile/privacy_options' - tag: Documentation - text: Mobile Session Replay Privacy Options - - 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 + - link: '/session_replay/mobile' + tag: Documentation + text: Mobile Session Replay + - link: '/session_replay/mobile/privacy_options' + tag: Documentation + text: Mobile Session Replay Privacy Options + - link: '/session_replay/mobile/setup_and_configuration' + tag: Documentation + text: Setup and Configure Mobile Session Replay + - link: '/session_replay/mobile/troubleshooting' + tag: Documentation + text: Troubleshoot Mobile Session Replay + - link: '/session_replay' + tag: Documentation + text: Session Replay --- ## Overview diff --git a/content/en/session_replay/mobile/privacy_options.md b/content/en/session_replay/mobile/privacy_options.md new file mode 100644 index 00000000000..764ea71d048 --- /dev/null +++ b/content/en/session_replay/mobile/privacy_options.md @@ -0,0 +1,3376 @@ +--- +title: Mobile Session Replay Privacy Options +description: Configure privacy options for Mobile Session Replay. +aliases: + - /real_user_monitoring/session_replay/mobile/privacy_options + - /product_analytics/session_replay/mobile/privacy_options +further_reading: + - link: /session_replay/mobile + tag: Documentation + text: Mobile Session Replay + - link: /session_replay/mobile/app_performance + tag: Documentation + text: How Mobile Session Replay Impacts App Performance + - link: /session_replay/mobile/setup_and_configuration + tag: Documentation + text: Setup and Configure Mobile Session Replay + - link: /session_replay/mobile/troubleshooting + tag: Documentation + text: Troubleshoot Mobile Session Replay + - link: /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

+
    +
  • + Privacy overrides, aside from the hidden and + touch options, are not supported for WebViews. You can + primarily manage their privacy using the + browser SDK privacy settings. +
  • +
  • + When a WebView is marked as hidden, it is replaced by a + placeholder in the replay. However, the WebView itself continues to + collect and send data. To avoid this, it is recommended to use + browser SDK privacy settings + for managing WebView privacy, as they provide more targeted control. +
  • +
+

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/session_replay/mobile/privacy_options.mdoc.md b/content/en/session_replay/mobile/privacy_options.mdoc.md new file mode 100644 index 00000000000..7d51c570498 --- /dev/null +++ b/content/en/session_replay/mobile/privacy_options.mdoc.md @@ -0,0 +1,30 @@ +--- +title: Mobile Session Replay Privacy Options +description: Configure privacy options for Mobile Session Replay. +aliases: + - /real_user_monitoring/session_replay/mobile/privacy_options + - /product_analytics/session_replay/mobile/privacy_options +content_filters: + - trait_id: platform + option_group_id: rum_sdk_platform_options_v2 + label: "SDK" +further_reading: + - link: '/session_replay/mobile' + tag: Documentation + text: Mobile Session Replay + - link: '/session_replay/mobile/app_performance' + tag: Documentation + text: How Mobile Session Replay Impacts App Performance + - link: '/session_replay/mobile/setup_and_configuration' + tag: Documentation + text: Setup and Configure Mobile Session Replay + - link: '/session_replay/mobile/troubleshooting' + tag: Documentation + text: Troubleshoot Mobile Session Replay + - link: '/session_replay' + tag: Documentation + text: Session Replay +--- + +{% partial file="real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md" /%} + diff --git a/content/en/real_user_monitoring/session_replay/mobile/setup_and_configuration.mdoc.md b/content/en/session_replay/mobile/setup_and_configuration.mdoc.md similarity index 100% rename from content/en/real_user_monitoring/session_replay/mobile/setup_and_configuration.mdoc.md rename to content/en/session_replay/mobile/setup_and_configuration.mdoc.md diff --git a/content/en/real_user_monitoring/session_replay/mobile/troubleshooting.md b/content/en/session_replay/mobile/troubleshooting.md similarity index 90% rename from content/en/real_user_monitoring/session_replay/mobile/troubleshooting.md rename to content/en/session_replay/mobile/troubleshooting.md index 7d496c7e29e..aa9bca3fd69 100644 --- a/content/en/real_user_monitoring/session_replay/mobile/troubleshooting.md +++ b/content/en/session_replay/mobile/troubleshooting.md @@ -3,16 +3,16 @@ title: Troubleshooting Mobile Session Replay description: How to troubleshoot Mobile Session Replay. aliases: further_reading: - - link: '/real_user_monitoring/session_replay/mobile' + - link: '/session_replay/mobile' tag: Documentation text: Mobile Session Replay - - link: '/real_user_monitoring/session_replay/mobile/setup_and_configuration' + - link: '/session_replay/mobile/setup_and_configuration' tag: Documentation text: Setup and Configure Mobile Session Replay - - link: '/real_user_monitoring/session_replay/mobile/app_performance' + - link: '/session_replay/mobile/app_performance' tag: Documentation text: How Mobile Session Replay Impacts App Performance - - link: '/real_user_monitoring/session_replay/mobile/privacy_options' + - link: '/session_replay/mobile/privacy_options' tag: Documentation text: Mobile Session Replay Privacy Options - link: '/real_user_monitoring/session_replay' @@ -66,4 +66,4 @@ At any time during the lifetime of the host app, it's possible to change the tra {{< partial name="whats-next/whats-next.html" >}} -[1]: /real_user_monitoring/session_replay/mobile/privacy_options/?platform=ios&tab=as-wrappers#image-masking +[1]: /session_replay/mobile/privacy_options/?platform=ios&tab=as-wrappers#image-masking diff --git a/content/en/real_user_monitoring/session_replay/playlists.md b/content/en/session_replay/playlists.md similarity index 96% rename from content/en/real_user_monitoring/session_replay/playlists.md rename to content/en/session_replay/playlists.md index c6603e8642f..2e2a9732538 100644 --- a/content/en/real_user_monitoring/session_replay/playlists.md +++ b/content/en/session_replay/playlists.md @@ -3,12 +3,12 @@ title: Session Replay Playlists description: Learn how to create and use Playlists for organizing Session Replays. aliases: further_reading: - - link: '/real_user_monitoring/session_replay' + - link: '/session_replay' tag: Documentation text: Session Replay - link: 'https://www.datadoghq.com/blog/datadog-rum-session-replay-playlists/' tag: Blog - text: Organize and analyze related session replays with Playlists in Datadog RUM + text: Organize and analyze related session replays with Playlists in Datadog --- ## Overview @@ -84,4 +84,4 @@ By default, Session Replay retention is 30 days. With [extended retention][2], y {{< partial name="whats-next/whats-next.html" >}} [1]: https://app.datadoghq.com/rum/replay/playlists -[2]: /real_user_monitoring/session_replay/#retention +[2]: /session_replay/#retention diff --git a/data/partials/home.yaml b/data/partials/home.yaml index d73d7dfd273..f46b4f33de9 100644 --- a/data/partials/home.yaml +++ b/data/partials/home.yaml @@ -123,6 +123,10 @@ nav_sections: link: product_analytics/ icon: product-analytics desc: Gain insight into user behavior and make data-driven product decisions + - title: Session Replay + link: session_replay/ + icon: session-replay + desc: Capture and visually replay the user experience of your users - title: Mobile Application Testing link: mobile_app_testing/ icon: mobile diff --git a/layouts/shortcodes/mdoc/en/real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md b/layouts/shortcodes/mdoc/en/real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md index 3aa4e9e5d48..f86c03eb792 100644 --- a/layouts/shortcodes/mdoc/en/real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md +++ b/layouts/shortcodes/mdoc/en/real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md @@ -1485,5 +1485,5 @@ The following chart shows how we apply different image masking strategies: - Masked {% /table %} -[1]: /real_user_monitoring/session_replay/privacy_options +[1]: /session_replay/browser/privacy_options [2]: https://github.com/DataDog/dd-sdk-reactnative diff --git a/layouts/shortcodes/mdoc/en/real_user_monitoring/session_replay/setup_and_configuration.mdoc.md b/layouts/shortcodes/mdoc/en/real_user_monitoring/session_replay/setup_and_configuration.mdoc.md index 1c8a2d6781d..dc1dd45a182 100644 --- a/layouts/shortcodes/mdoc/en/real_user_monitoring/session_replay/setup_and_configuration.mdoc.md +++ b/layouts/shortcodes/mdoc/en/real_user_monitoring/session_replay/setup_and_configuration.mdoc.md @@ -586,7 +586,7 @@ DatadogSdk.instance.sdkVerbosity = CoreLoggerLevel.debug; See [Privacy Options][2]. [1]: /real_user_monitoring/application_monitoring/ios/web_view_tracking -[2]: /real_user_monitoring/session_replay/mobile/privacy_options +[2]: /session_replay/mobile/privacy_options [3]: https://reactnative.dev/architecture/landing-page [4]: https://central.sonatype.com/artifact/com.datadoghq/dd-sdk-kotlin-multiplatform-session-replay/versions [5]: /real_user_monitoring/android/?tab=kotlin @@ -601,16 +601,16 @@ See [Privacy Options][2]. [14]: /real_user_monitoring/application_monitoring/react_native/setup [15]: https://yarnpkg.com/package?q=datadog%20react%20native%20ses&name=%40datadog%2Fmobile-react-native-session-replay [16]: https://www.npmjs.com/package/@datadog/mobile-react-native-session-replay?activeTab=versions -[17]: /real_user_monitoring/session_replay/mobile/privacy_options/?tab=reactnative +[17]: /session_replay/mobile/privacy_options/?tab=reactnative [18]: https://github.com/DataDog/dd-sdk-reactnative [19]: https://github.com/DataDog/dd-sdk-android/releases/tag/2.8.0 [20]: /real_user_monitoring/application_monitoring/android/web_view_tracking/?tab=android#instrument-your-web-views -[21]: /real_user_monitoring/session_replay/browser/#setup +[21]: /session_replay/browser/#setup [22]: https://github.com/DataDog/dd-sdk-ios/releases/tag/2.13.0 [23]: /real_user_monitoring/application_monitoring/ios/web_view_tracking/?tab=ios#instrument-your-web-views [24]: /real_user_monitoring/application_monitoring/kotlin_multiplatform/web_view_tracking/?tab=kotlinmultiplatform#instrument-your-web-views [25]: /real_user_monitoring/application_monitoring/web_view_tracking/?tab=reactnative#instrument-your-web-views -[26]: /real_user_monitoring/session_replay/browser/#setup +[26]: /session_replay/browser/#setup [27]: https://reactnative.dev/architecture/landing-page [28]: https://docs.datadoghq.com/real_user_monitoring/application_monitoring/flutter/setup?tab=rum [29]: https://pub.dev/packages/datadog_session_replay From aea8daf56b21ea1ae0a8090a167218f773454439 Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Fri, 19 Dec 2025 14:54:14 -0800 Subject: [PATCH 04/15] more --- .../session_replay/mobile/privacy_options.md | 3373 +++++++++++++++++ .../mobile/setup_and_configuration.md | 1343 +++++++ .../mobile/privacy_options.mdoc.md | 26 - .../session_replay/mobile/privacy_options.md | 142 +- 4 files changed, 4787 insertions(+), 97 deletions(-) create mode 100644 content/en/product_analytics/session_replay/mobile/privacy_options.md create mode 100644 content/en/product_analytics/session_replay/mobile/setup_and_configuration.md delete mode 100644 content/en/real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md diff --git a/content/en/product_analytics/session_replay/mobile/privacy_options.md b/content/en/product_analytics/session_replay/mobile/privacy_options.md new file mode 100644 index 00000000000..4c54a11fffc --- /dev/null +++ b/content/en/product_analytics/session_replay/mobile/privacy_options.md @@ -0,0 +1,3373 @@ +--- +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

+
    +
  • + Privacy overrides, aside from the hidden and + touch options, are not supported for WebViews. You can + primarily manage their privacy using the + browser SDK privacy settings. +
  • +
  • + When a WebView is marked as hidden, it is replaced by a + placeholder in the replay. However, the WebView itself continues to + collect and send data. To avoid this, it is recommended to use + browser SDK privacy settings + for managing WebView privacy, as they provide more targeted control. +
  • +
+

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 new file mode 100644 index 00000000000..a15bb19ca0a --- /dev/null +++ b/content/en/product_analytics/session_replay/mobile/setup_and_configuration.md @@ -0,0 +1,1343 @@ +--- +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.mdoc.md b/content/en/real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md deleted file mode 100644 index bb7ff30a54a..00000000000 --- a/content/en/real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Mobile Session Replay Privacy Options -description: Configure privacy options for Mobile Session Replay. -content_filters: - - trait_id: platform - option_group_id: rum_sdk_platform_options_v2 - label: "SDK" -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 ---- - -{% partial file="real_user_monitoring/session_replay/mobile/privacy_options.mdoc.md" /%} diff --git a/content/en/session_replay/mobile/privacy_options.md b/content/en/session_replay/mobile/privacy_options.md index 764ea71d048..de34cc6947c 100644 --- a/content/en/session_replay/mobile/privacy_options.md +++ b/content/en/session_replay/mobile/privacy_options.md @@ -158,7 +158,7 @@ further_reading:
@@ -304,7 +304,7 @@ further_reading:
@@ -450,7 +450,7 @@ further_reading:
@@ -596,7 +596,7 @@ further_reading:

For performance reasons, large images (those exceeding 1000x1000 total @@ -630,7 +630,7 @@ further_reading:

@@ -776,7 +776,7 @@ further_reading:

Use the maskNonBundledOnly setting to replace non-bundled @@ -797,7 +797,7 @@ further_reading:

Select the mask_large_only setting, which replaces images @@ -812,7 +812,7 @@ further_reading:

Bundled images are those that use AssetImage as their image @@ -998,7 +998,7 @@ further_reading:

@@ -1261,7 +1261,7 @@ further_reading:
@@ -1432,13 +1432,13 @@ further_reading:

Text and input override

To override text and input privacy in Android classic view, use @@ -1510,7 +1510,7 @@ further_reading:

To override text and input privacy in UIKit views, use @@ -1592,7 +1592,7 @@ further_reading:

To override text and input privacy in Flutter, use the @@ -1639,7 +1639,7 @@ further_reading:

To override image privacy in Android classic view, use @@ -1711,7 +1711,7 @@ further_reading:

To override image privacy in UIKit views, use @@ -1798,7 +1798,7 @@ further_reading:

To override image privacy in Flutter, use the @@ -1841,7 +1841,7 @@ further_reading:

To override touch privacy in Android classic view, use @@ -1912,7 +1912,7 @@ further_reading:

To override touch privacy in UIKit views, use @@ -2000,7 +2000,7 @@ further_reading:

To override touch privacy in Flutter, use the @@ -2063,7 +2063,7 @@ further_reading:

Use setSessionReplayHidden(hide = true) to hide the @@ -2132,7 +2132,7 @@ further_reading:

In UIKit views, use dd.sessionReplayOverrides.hide to hide @@ -2324,7 +2324,7 @@ further_reading:

To hide a widget tree in Flutter, use the @@ -2370,7 +2370,7 @@ further_reading:

Privacy overrides are fully supported in React Native starting from @@ -2813,7 +2813,7 @@ further_reading:

Sensitive text can be detected in: