Skip to content

Flutter SESSION REPLAY

Prerequisites

  • Ensure you have set up and initialized Flutter RUM configuration, and enabled View monitoring collection.
  • Flutter SESSION REPLAY requires installation of both ft_mobile_agent_flutter and ft_session_replay_flutter.
  • Starting from ft_mobile_agent_flutter 0.5.7, Session Replay capability is no longer built-in. Session Replay APIs need to be imported from ft_session_replay_flutter.
  • Android side uses ft-sdk:1.7.3, ft-native:1.1.3, and ft-session-replay:0.1.6-beta01. iOS side uses FTMobileSDK 1.6.5 and FTMobileSDK/FTSessionReplay 1.6.5.
  • The iOS project Deployment Target needs to be set to 12.0 or higher.
  • It is recommended to complete RUM initialization first, then initialize Session Replay, ensuring that contexts like app_id, session_id, view_id are already established.

Installation

Execute in the project directory:

flutter pub add ft_mobile_agent_flutter
flutter pub add ft_session_replay_flutter

This will add dependencies to the package's pubspec.yaml:

dependencies:
  ft_mobile_agent_flutter: [latest_version]
  ft_session_replay_flutter: [session_replay_version]

When debugging an unpublished version locally, you can use path dependencies:

dependencies:
  ft_mobile_agent_flutter:
    path: /path/to/ft-sdk-flutter
  ft_session_replay_flutter:
    path: /path/to/ft-sdk-flutter/packages/ft_session_replay_flutter

Then execute:

flutter pub get

Additional iOS Configuration

Confirm that the minimum version in the app's ios/Podfile is not lower than 12.0:

platform :ios, '12.0'

Update CocoaPods dependencies:

cd ios
pod install

If CocoaPods reports conflicts with FTMobileSDK version or Deployment Target, first check if there are other dependencies in the project locking a lower version of FTMobileSDK or iOS deployment version.

Code Usage

Import both the main package and the Session Replay package in Dart code:

import 'package:ft_mobile_agent_flutter/ft_mobile_agent_flutter.dart';
import 'package:ft_session_replay_flutter/ft_session_replay_flutter.dart';

Recommended initialization order:

  1. WidgetsFlutterBinding.ensureInitialized()
  2. FTMobileFlutter.sdkConfig(...)
  3. FTRUMManager().setConfig(...)
  4. FTSessionReplayManager().setConfig(...)
  5. Wrap the Flutter view tree to be recorded with SessionReplayCapture
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await FTMobileFlutter.sdkConfig(
    datawayUrl: datawayUrl,
    cliToken: cliToken,
    serviceName: serviceName,
    debug: true,
  );

  await FTRUMManager().setConfig(
    androidAppId: androidAppId,
    iOSAppId: iOSAppId,
    sampleRate: 1.0,
    enableUserResource: true,
    enableNativeAppUIBlock: true,
    enableTrackNativeCrash: true,
  );

  await FTSessionReplayManager().setConfig(
    FTSessionReplayConfig(
      sampleRate: 1.0,
      sessionReplayOnErrorSampleRate: 0.0,
      touchPrivacy: FTTouchPrivacyLevel.show,
      textAndInputPrivacy: FTTextAndInputPrivacyLevel.maskSensitiveInputs,
      imagePrivacy: FTImagePrivacyLevel.maskAll,
      enableSwiftUI: false,
    ),
  );

  runApp(
    SessionReplayCapture(
      key: const ValueKey('session-replay-root'),
      child: const MyApp(),
    ),
  );
}

If the application wraps pages uniformly via MaterialApp.builder, you can also use SessionReplayCapture in the builder:

MaterialApp(
  builder: (BuildContext context, Widget? child) {
    return SessionReplayCapture(
      key: const ValueKey('session-replay-root'),
      child: child ?? const SizedBox.shrink(),
    );
  },
);
Property Type Required Meaning
sampleRate double No Sampling rate, range [0,1], 0 means no collection, 1 means full collection, default value is 1. This sampling rate is applied on top of the RUM sampling rate.
sessionReplayOnErrorSampleRate double No Session Replay sampling rate for error scenarios, range [0,1], 0 means no collection, 1 means full collection, default value is 0.
touchPrivacy FTTouchPrivacyLevel No Sets the privacy level for touch behaviors. FTTouchPrivacyLevel.show displays touch behaviors; FTTouchPrivacyLevel.hide hides touch behaviors. Default is FTTouchPrivacyLevel.hide.
textAndInputPrivacy FTTextAndInputPrivacyLevel No Sets the privacy level for text and input content. maskSensitiveInputs only masks sensitive inputs; maskAllInputs masks all input content; maskAll masks all text and input content. Default is maskAll.
imagePrivacy FTImagePrivacyLevel No Sets the privacy level for image content. maskNone does not mask images; maskLargeOnly uses the native SDK's partial image masking strategy; maskAll masks all images. Default is maskAll.
enableLinkRUMKeys List No Associates fields from the RUM Context corresponding to the set keys to the session replay data, which can be used to implement session replay data sharding.
enableSwiftUI bool No iOS: Whether to enable native SwiftUI session replay recording, default is false. Flutter Widget recording still requires wrapping the view tree with SessionReplayCapture.

RUM View Association

Session Replay data needs to be associated with the RUM View context. Please use FTRouteObserver to automatically collect page switches, or manually call FTRUMManager().starView(...) and FTRUMManager().stopView(...) in custom page lifecycles.

MaterialApp(
  navigatorObservers: [
    FTRouteObserver(),
  ],
);

If the base SDK or RUM is not initialized, Session Replay initialization will not cause the application to crash, but will not generate uploadable replay data.

Privacy Overrides

SessionReplayPrivacy can be used to set privacy overrides for a local Flutter view tree. Privacy overrides apply to its child views. When multiple layers of overrides exist, child views will use the privacy configuration of the nearest parent.

SessionReplayPrivacy(
  textAndInputPrivacyLevel: FTTextAndInputPrivacyLevel.maskAll,
  imagePrivacyLevel: FTImagePrivacyLevel.maskAll,
  touchPrivacyLevel: FTTouchPrivacyLevel.hide,
  child: child,
);

Viewing SESSION REPLAY

The way to view SESSION REPLAY on mobile is the same as on the web. You can refer to Web SESSION REPLAY Access Method.