Respectlytics Respect lytics
Menu
Flutter Deep link open Privacy-first

How to track deep-link opens in Flutter without personal data

Deep-link opens carry rich attribution payload by default — UTM parameters, source campaigns, referral codes, full URLs — and most analytics SDKs ingest all of it on open. Respectlytics helps developers avoid collecting personal data in the first place: in Flutter, deep-link open is one named event, optionally differentiated by source via the event name. The full URL stays in your routing code; only the high-level entry point reaches analytics. Below: handlers for Universal Links, App Links, and custom schemes; what to keep out of the event name; and how to compute campaign attribution differently.

Fire the call inside your deep-link handler — SceneDelegate.scene(_:continue:) on iOS, Intent filter receiver on Android, the equivalent React Native Linking handler, Flutter's uni_links callback. Don't pass the URL or its query parameters.

Install the Flutter SDK

yaml Respectlytics
# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  respectlytics_flutter: ^3.0.0

Pure Dart — no platform channels for analytics. Same code on every platform Flutter compiles to (iOS, Android, web, macOS, Windows, Linux). On web, events are sent via the REST API; mobile platforms use the same path.

Initialize Respectlytics in Flutter

dart Respectlytics
import 'package:flutter/material.dart';
import 'package:respectlytics_flutter/respectlytics_flutter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Respectlytics.configure(appKey: '<YOUR_APP_KEY>');
  runApp(const MyApp());
}

Initialize in main() after WidgetsFlutterBinding.ensureInitialized() and before runApp(). The future completes immediately on configuration; events queued before completion are flushed once the network is available.

Track the event in Flutter

dart Respectlytics
import 'package:respectlytics_flutter/respectlytics_flutter.dart';
import 'package:uni_links/uni_links.dart';

Future<void> initDeepLinkTracking(void Function(Uri) handle) async {
  final initial = await getInitialUri();
  if (initial != null) {
    Respectlytics.track('deeplink_open');
    handle(initial);
  }
  uriLinkStream.listen((uri) {
    if (uri == null) return;
    Respectlytics.track('deeplink_open');
    handle(uri);
  });
}

On Flutter 3.16+, prefer app_links over uni_links — same shape API. The URL goes to your routing handler, not into the track call.

Privacy & implementation notes

A deep-link URL often contains the user's tracking ID, the campaign source, the referrer, and sometimes a session token — concatenated into a single free-form string. Respectlytics's API rejects free-form strings as event metadata. Your routing code keeps the URL; analytics gets the event name.

Install attribution and deep-link open are different signals. Install attribution requires server-side callbacks from the App Store / Play Store. Deep-link open is the in-app signal that the user navigated via a link. Don't use the open event as a proxy for install — they fire at different times for different populations.

The Flutter SDK is pure Dart. No MethodChannel, no platform-specific iOS or Android plugin code. The same code runs on every platform Flutter supports — including web and desktop targets. This eliminates one common audit surface ("what's the Android implementation doing?").

Always initialize after WidgetsFlutterBinding.ensureInitialized() and before runApp(). If you skip the binding step, the configure call will throw on platforms that need a binding for asynchronous I/O. The SDK documentation example uses this pattern by default.

How this compares to other analytics SDKs

Deep-link open eventFirebase AnalyticsMixpanelRespectlytics
Full URL storedOften (via Dynamic Links)OftenRejected by API
UTM parameters as event propertiesYes (default for web tracking)YesRejected by API
Referral code as parameterRecommendedRecommendedUse distinct event_name (top-N) or skip
Per-campaign attributionPer-userPer-userSession-scoped, top-N campaigns only
Click-through rate (link → app open)With Dynamic LinksWith server-side joinOut of scope (use server-side analytics)

Frequently asked questions

How do we know which campaign drove an install?

Server-side, not in product analytics. App Store Connect (Apple Search Ads) and Play Console (Play Store referrer API) deliver install attribution to your backend via server-to-server callbacks. Respectlytics is for in-app product engagement — different question, different system of record.

What about top-N campaign tracking via event names?

If you have a small set of high-volume campaigns (under 10), distinct event names work: deeplink_open_summer_sale, deeplink_open_press_pickup. The long tail bucketed as deeplink_open_other. For high-cardinality campaign ID tracking, use server-side attribution instead.

Should we distinguish Universal Links / App Links from custom schemes?

If your app supports both (which is common during a migration), use distinct event names: deeplink_open_universal, deeplink_open_custom_scheme. The rate of each tells you how successfully you've migrated traffic to the modern API.

What if the deep link triggers in-app navigation but no other events?

Common with deep links to settings or specific content. Fire deeplink_open anyway — the open itself is the signal. If the user goes on to convert in the same session, the funnel groups them together via session_id.

Related guides

Track what matters. Collect nothing you don't.

Five-field event schema, RAM-only event queue, no IDFA, no AAID, no persistent user IDs. Helps developers avoid collecting personal data in the first place.