---
title: Experience Analytics extension - Flutter
description: Understand the benefits of upgrading to the CSQ SDK
lastUpdated: 12 June 2026
source_url:
  html: https://docs.contentsquare.com/en/csq-sdk-flutter/product-analytics/dxae-setup/
  md: https://docs.contentsquare.com/en/csq-sdk-flutter/product-analytics/dxae-setup/index.md
---

> Documentation index: https://docs.contentsquare.com/llms.txt
> Use this file to discover all available pages before exploring further.

Use this page to set up the Mobile Experience Analytics extension for Contentsquare Product Analytics.

This will supercharge the Product Analytics platform with:

* Powerful Session Replay
* Analysis capabilities of Mobile API Errors and Crashes

This guide assumes that you have already implemented the [CSQ SDK for Product Analytics](../).

## Enable the extension in the Product Analytics UI

1. In Product Analytics, navigate to **Account** > **Manage** > **Replays & Heatmaps**.

2. If this is your first time setting up Session Replay, select the checkbox to accept the terms and conditions.

3. Click **Add web or mobile app** to launch the setup wizard. There is one configuration per app.

4. Select **Mobile** as platform.

5. Give your app a name and choose a storage location (**US** or **EU**).

6. Set a sampling rate for how many sessions to record.

7. Configure replay settings:

   * **App ID**: enter the bundle ID of your app (for example, `com.companyname.appname`).
   * **Quality Settings**: choose the recording fidelity for Wi-Fi and Cellular connections. The default for both is Medium; keep Cellular equal to or lower than Wi-Fi.
   * **User Consent**: enable this if your app requires explicit opt-in before recording. See [Privacy docs](../privacy/#opt-in) for the opt-in API.

8. Click **Save and Continue** to finish the wizard.

Two configurations required

Flutter apps require two separate mobile configurations — one for iOS and one for Android. Repeat the steps above for each platform, entering the appropriate bundle ID each time.

## Enable error and crash collection

Error and crash collection is managed separately from the setup wizard. Navigate to **Account** > **Manage** > **Replays & Heatmaps**, click **Edit** next to your app configuration, then scroll to the relevant section under **General Settings**:

* **Error Capture**: toggles for **API Errors** and **Custom Errors**.
* **Crashes Capture**: toggle for **Crashes & Flutter Errors**.

Click **Save** when finished.

## Session Replay masking

The Session Replay feature replays every interaction of your users with your app. To respect the user's right to privacy, the CSQ SDK:

* Masks everything by default
* Allows you to control which part of the user interface is collected via our [Masking rules](#masking-rules)

Warning

When using Contentsquare with Flutter, if you decide to use unmasked elements leading to collection of new data or use already collected data but for a different purpose, it is up to you to update your app's privacy documentation accordingly. Here are some common examples of data collected via unmasked Session Replay: Search history, purchase history, advertising data, etc. See [Types of data and purpose](https://docs.contentsquare.com/en/csq-sdk-flutter/experience-analytics/privacy/) for details about the data collected by the Contentsquare Flutter SDK.

**Important:** Contentsquare is not intended nor designed to collect sensitive personal data (such as health, financial, racial data). It is the customer's responsibility not to send any sensitive personal data to Contentsquare.

### Masking mechanisms

Masking depends on the type of element:

* **Images**: A blurred representation is sent in place of the original content.
* **SVG images**: A blurred representation is sent in place of the original content.
* **CustomPaint**: custom-made `CustomPaint` elements are not collected. Instead, a blurred representation is sent in place of the original content. [Framework specific decorative `CustomPaint`](https://docs.contentsquare.com/en/csq-sdk-flutter/experience-analytics/session-replay/#unmaskable-framework-specific-custompaint-classes) that do not contain sensitive data are still collected.
* **Text**: Replaced by \* (asterisk) characters, matching the original character count. Whitespace characters (spaces, tabs, line breaks) are preserved. For instance, `the lazy fox` is collected as `*** **** ***`. All other visual properties (text color, background color, alignment, etc.) are collected.
* **TextFields**: Same as Text
* **TextField with `obscureText`**: Both the obscured text and the briefly revealed character are replaced by • (bullet).
* **Other types**: no specific data is collected but visual properties are collected.
* **Icons**: Single characters belonging to the Private Use Area `U+E000..U+F8FF` are collected.

If you believe a particular element might disclose personal data through any of these properties, you must mask it using one of the methods outlined below. A reliable method to assess how a view is rendered in a replay is to navigate to the desired view with the CS SDK active, then use the [quick replay link](https://docs.contentsquare.com/en/csq-sdk-flutter/experience-analytics/session-replay/#access-the-replay).

#### Masking example

Here's an illustration of a masked view:

`Original` -> `Replay fully unmasked` -> `Replay fully masked`

![](https://docs.contentsquare.com/_astro/flutter-sr-masking-example_from_3_19.CrHM_fsR_Z1obhya.webp)

### Masking rules

Masking rules can be applied in two ways:

1. **Through remote masking configuration in the CSQ Console (for admin users):** These configurations are managed directly in the Console and take effect for all sessions as soon as the app is restarted or brought to the foreground. See [How to customize masking rules from the Data Masking tab ↗](https://support.contentsquare.com/hc/en-us/articles/37271848716561-How-to-customize-masking-rules-from-the-Data-Masking-tab-Apps) on the Help Center.
2. **Using public masking APIs in the SDK (for mobile application developers):** These configurations require developer implementation and will be applied only after the mobile app has gone through its release cycle.

Masking rules set via the CSQ Console or the public APIs are applied according to different priorities, as described below. The SDK determines whether a view is masked by evaluating the rules in the order specified below. Once a rule is triggered, the state is set, and subsequent rules are not applied:

When using `CSQMask` and `CSQMaskingConfig`, it's essential to understand the priority of masking rules in the widget tree. The masking rules specified in a `CSQMask` widget will affect its descendants, and if nested scopes are used, the innermost (closest) scope takes precedence.

Once a rule is triggered, the state is set, and subsequent rules are not applied:

| Rule | Configured via |
| - | - |
| 1. The app or plugin version is fully masked | [Data Masking tab in the CSQ Console ↗](https://support.contentsquare.com/hc/en-us/articles/37271848716561-How-to-customize-masking-rules-from-the-Data-Masking-tab-Apps) |
| 2. Remote Text or Image masking is defined | [Data Masking tab in the CSQ Console ↗](https://support.contentsquare.com/hc/en-us/articles/37271848716561-How-to-customize-masking-rules-from-the-Data-Masking-tab-Apps) |
| 3. The `CSQMaskingConfig` object provided to the `start()` method sets the masking rules for the entire app. | API |
| 4. The `CSQMaskingConfig` object provided to a `CSQMask` widget sets the masking rules for its child and descendants. | API |
| 5. Remote Text or Image unmasking is defined | [Data Masking tab in the CSQ Console ↗](https://support.contentsquare.com/hc/en-us/articles/37271848716561-How-to-customize-masking-rules-from-the-Data-Masking-tab-Apps) |
| 6. Otherwise the widget remains masked except for `CustomPaints` and `SvgImages` | default |

### Public Masking APIs

#### Default masking

By default all images, text, and Text fields will be masked. SVGs and CustomPaints are not masked.

#### Masking/Un-masking in Flutter

`CSQMask` is a Flutter widget that applies specified masking rules to its descendant widgets. This can be used when you want to mask sensitive information during Session Replays, such as user data or private texts.

`CSQMaskingConfig` is a class that determines what type of content should be masked during Session Replays. You can customize the masking behavior by setting the masking options for texts, text fields, and images.

#### Handle masking

To mask or unmask content, wrap the desired widgets with the `CSQMask` widget and provide a `CSQMaskingConfig` object to configure the masking rules.

Here's an example of how to use `CSQMask`:

```dart
import 'package:contentsquare/csq.dart';


CSQMask(
  maskingConfig: CSQMaskingConfig.maskAll(),
  child: const Text('Hello world'),
);
```

In this example, `CSQMaskingConfig.maskAll()` is used to mask the `Text` widget.

You can also use nested `CSQMask` widgets to apply different masking rules to different parts of your widget tree. Here's an example:

```dart
import 'package:contentsquare/csq.dart';


CSQMask(
  maskingConfig: CSQMaskingConfig.maskAll(),
  child: Column(
    children: [
      const Text('This text will be masked'),
      CSQMask(
        maskingConfig: CSQMaskingConfig(maskTexts: false),
        child: Text('This text will NOT be masked'),
      ),
    ],
  ),
);
```

In this example, the first `Text` widget will be masked, while the second one will not be masked due to the `maskTexts: false` option in the nested `CSQMask`.

#### How to use `CSQMaskingConfig`

`CSQMaskingConfig` allows you to configure the masking behavior for different types of content:

* `maskTexts`: If set to `true`, any widget that creates a `RenderParagraph` (example: `Text`, `RichText`) will be masked.
* `maskTextFields`: If set to `true`, any widget that creates a `RenderEditable` (example: `TextFormField`, `TextField`) will be masked.
* `maskImages`: If set to `true`, any widget that creates an image (example: `Image`, `BoxDecoration.image`) will be masked.
* `maskSvgImages`: If set to `true`, any widget that creates an SVG image through `flutter_svg` will be masked.
* `maskCustomPaints`: If set to `true`, any custom-made widget that creates a `CustomPaint` will be masked. [Framework specific decorative `CustomPaint`](https://docs.contentsquare.com/en/csq-sdk-flutter/experience-analytics/session-replay/#unmaskable-framework-specific-custompaint-classes) not containing any sensitive data are not masked.
* `maskCharts`: If set to `true`, any widget that creates a chart using the [`fl_chart` ↗](https://pub.dev/packages/fl_chart) package will be masked.

You can create a custom `CSQMaskingConfig` object by using the constructor:

```dart
import 'package:contentsquare/csq.dart';


const CSQMaskingConfig({
  bool? maskTexts,
  bool? maskImages,
  bool? maskTextFields,
  bool? maskSvgImages,
  bool? maskCharts,
  bool? maskCustomPaints,
})
```

For easier readability and convenience, you can use the following factory constructors:

* `CSQMaskingConfig.maskAll()`: Returns a `CSQMaskingConfig` object with all values set to `true`, meaning everything will be masked.
* `CSQMaskingConfig.unMaskAll()`: Returns a `CSQMaskingConfig` object with all values set to `false`, meaning nothing will be masked.

If any masking parameter is omitted in the `CSQMaskingConfig` object, its value is inherited from the nearest `SessionMaskingScope` widget in the widget tree.

Note

By default, CSQ masks all types of content (texts, text fields, and images) except the SVG images and CustomPaints during Session Replays. It achieves this by providing a default `CSQMaskingConfig` object if none is specified. The default configuration masks everything, ensuring that sensitive information is protected. However, you can override the default masking behavior by providing your own `CSQMaskingConfig` object when calling the `start()` method. This allows you to customize the masking rules for your app according to your requirements.

Note

If you did not include any sensitive content in `CustomPaint`s or SVG images, prefer to use `CSQMaskingConfig` with `maskCustomPaints` and `maskSvgImages` set to false, to avoid unnecessary masking and guarantee the best Session Replay fidelity.


```json
{"@context":"https://schema.org","@type":"TechArticle","headline":"Experience Analytics extension","description":"Understand the benefits of upgrading to the CSQ SDK","url":"https://docs.contentsquare.com/en/csq-sdk-flutter/product-analytics/dxae-setup/","inLanguage":"en","dateModified":"2026-06-12T11:40:35+02:00","publisher":{"@type":"Organization","name":"Contentsquare","url":"https://www.contentsquare.com/"},"isPartOf":{"@type":"WebSite","@id":"https://docs.contentsquare.com/#website","name":"Contentsquare Technical Documentation","url":"https://docs.contentsquare.com/"}}
```