---
title: Adobe Analytics - Flutter
description: Leverage our native integration to use Adobe Analytics segments in Contentsquare, with the CSQ Flutter SDK
lastUpdated: 05 December 2025
source_url:
  html: https://docs.contentsquare.com/en/csq-sdk-flutter/experience-analytics/adobe-analytics/
  md: https://docs.contentsquare.com/en/csq-sdk-flutter/experience-analytics/adobe-analytics/index.md
---

Analyze your data from anywhere in the customer journey using your Adobe Analytics segments.\
Contentsquare allows you to use your Adobe Analytics segments in every Contentsquare feature (Journey Analysis, Page Comparator, Session Replay).

Warning

Sessions without at least one screenview will be discarded.\
You should implement your screen tracking plan first, to have your Adobe Analytics integration work.\
See [Track screens](../track-screens/).

## Prerequisites

1. Follow the instructions from [Adobe Analytics for mobile apps ↗](https://support.contentsquare.com/hc/en-us/articles/37271665881745)
2. Add the [`flutter_aepedge` package ↗](https://pub.dev/packages/flutter_aepedge) to your project and follow its instructions.

## Code implementation

Adobe SDK code requirements

On the native Android and iOS parts of your Flutter project, make sure you have followed the instructions of [Usage of `flutter_aepedge` ↗](https://pub.dev/packages/flutter_aepedge#usage).

**Why 30 minutes before sending a new csMatchingKey**

* 30 minutes is Contentsquare default session duration.
* Setting a value **higher** than 30 minutes would cause overlapping on our sessions, and would impact negatively the data import from Adobe.
* Setting a value **lower** than 30 minutes would make you to send more data to Adobe.\
  This could cause the variable to reach Adobe's threshold, causing Adobe to filter values, and potentially impact your billing.\
  See [Low-traffic value in Adobe Analytics ↗](https://experienceleague.adobe.com/docs/analytics/technotes/low-traffic.html)

Add the following code snippet in your application code. Add a call to the `sendCSMatchingKeyIfNeeded()` from within the `initState` of your application. Listen to `AppLifecycleState` change and call `sendCSMatchingKeyIfNeeded()` when the application resumed.

```dart
import 'package:contentsquare/csq.dart';
import 'package:flutter_aepedge/flutter_aepedge.dart';
// ... others imports




// TODO: Use your local storage. A package you can use is: https://pub.dev/packages/shared_preferences
final localStorage = LocalStorageFake();


@override
void initState() {
  // ... your code
  sendCSMatchingKeyIfNeeded();
  WidgetsBinding.instance.addObserver(this);
  // ... your code
}


@override
void dispose() {
  // ... your code
  WidgetsBinding.instance.removeObserver(this);
  super.dispose();
  // ... your code
}


@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  // Check if the app is in the foreground
  if (state == AppLifecycleState.resumed) {
    sendCSMatchingKeyIfNeeded();
  }
}


Future<void> sendCSMatchingKeyIfNeeded() async {
  // TODO: Implement your local storage. A package you can use is: https://pub.dev/packages/shared_preferences
  final csMatchingKeyTimestampMap = await localStorage.getMap(
    'csMatchingKey_creation_ts',
  );


  final csMatchingKeyIsNotGenerated = csMatchingKeyTimestampMap == null;
  if (csMatchingKeyIsNotGenerated) {
    await _submitNewCsMatchingKey();
    return;
  }


  final timestamp = DateTime.fromMillisecondsSinceEpoch(
    csMatchingKeyTimestampMap['timestamp'],
  );
  if (DateTime.now().difference(timestamp).inMinutes > 30) {
    // if the key is not valid anymore, submit a new one
    await _submitNewCsMatchingKey();
  }
  // if the key is still valid, do nothing
}


Future<void> _submitNewCsMatchingKey() async {
  // Generate the matching key and store it in the local storage
  final millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch;
  final csMatchingKeyValue = '${Random().nextDouble()}_$millisecondsSinceEpoch';


  await localStorage.setMap('csMatchingKey_creation_ts', {
    'csMatchingKey': csMatchingKeyValue,
    'timestamp': millisecondsSinceEpoch,
  });


  // Submit the matching key to Adobe
  final experienceEvent = ExperienceEvent({
    'xdmData': {'eventType': 'csMatchingKey_state'},
    'data': {'csMatchingKey': csMatchingKeyValue}
  });
  await Edge.sendEvent(experienceEvent);


  // Submit the matching key to CSQ
  await CSQ().addDynamicVar(DynamicVar.fromString(
    key: 'csMatchingKey',
    value: csMatchingKeyValue,
  ));
}
```
