Flutter SDK

The Flutter SDK is the primary Attriax runtime implementation and the best place to start when you want first-class mobile attribution, deep links, and lifecycle tracking.

SDK / Flutter

This section stays intentionally general. For detailed configuration, project-specific diagnostics, release context, and exact disclosure guidance, open the app workspace for your project.

Package surface

General guide for attriax_flutter. Use the app workspace when you need detailed setup steps, release context, and project-specific values.

What teams use it for

These are the runtime jobs the product already exposes through the SDK and the matching workspace tools.

Mobile-first runtime

Built for app-open attribution, install referrer handling, deferred deep links, and in-app routing.

Operational visibility

Pairs runtime tracking with analytics, crashes, diagnostics, and privacy helpers in the same workspace.

Good for shipping teams

Use one integration surface while the workspace handles platform-specific diagnostics and review steps.

Integration notes

Keep the public docs lightweight, then open the app workspace when you need the exact setup steps for your own release flow.

Capabilities

  • Initialize one SDK instance for the whole app and keep navigation tracking close to the runtime.
  • Wait for the initial deep link, handle deferred deep links, and subscribe to events that resolve after startup.
  • Inspect install referrer information on Android when it is available.
  • Track page views, custom events, sessions, crashes, and mobile token flows through the same SDK surface.

Notes

  • Flutter is the reference runtime for shared product behavior, so it is the most direct path for new mobile integrations.
  • Android and iOS are the strongest runtime targets. Desktop forwarding exists, but it is more manual and should be validated with diagnostics.
  • Use the app workspace when you need project-specific configuration, exact host values, and platform-specific setup status.

Install

Use the publishable Flutter package, then open the app workspace for detailed diagnostics and platform configuration.

Install command

flutter pub add attriax_flutter

Example

The snippet below mirrors the app workspace starting point while keeping the guide general instead of project-specific.

lib/main.dart

Initialize once, wait for the SDK, subscribe to deep links, and route resolved paths into your Flutter navigation stack.

1import 'dart:async';
2import 'package:flutter/material.dart';
3import 'package:attriax_flutter/attriax.dart';
4
5// Create one SDK instance for the whole application.
6final Attriax attriax = Attriax(
7  config: const AttriaxConfig(
8    appToken: 'ax_your_app_token',
9  ),
10);
11
12final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
13
14Future<void> main() async {
15  WidgetsFlutterBinding.ensureInitialized();
16
17  // Wait for the SDK before the UI starts.
18  await attriax.init();
19
20  runApp(const MyApp());
21}
22
23class MyApp extends StatelessWidget {
24  const MyApp({super.key});
25
26  
27  Widget build(BuildContext context) {
28    return MaterialApp(
29      navigatorKey: navigatorKey,
30      navigatorObservers: <NavigatorObserver>[
31        // This tracks page changes for normal Flutter navigation.
32        AttriaxNavigationObserver(attriax: attriax),
33      ],
34      routes: <String, WidgetBuilder>{
35        '/': (_) => const HomeScreen(),
36        '/promo': (_) => const PromoScreen(),
37        '/deep-link': (_) => const DeepLinkScreen(),
38      },
39    );
40  }
41}
42
43class HomeScreen extends StatefulWidget {
44  const HomeScreen({super.key});
45
46  
47  State<HomeScreen> createState() => _HomeScreenState();
48}
49
50class _HomeScreenState extends State<HomeScreen> {
51  StreamSubscription<AttriaxDeepLinkEvent>? _deepLinkSubscription;
52
53  
54  void initState() {
55    super.initState();
56
57    // Listen for deep links that resolve after startup.
58    _deepLinkSubscription = attriax.deepLinks.stream.listen(_handleDeepLinkEvent);
59
60    // Load startup attribution without blocking the first frame.
61    unawaited(_loadStartupAttribution());
62  }
63
64  
65  void dispose() {
66    unawaited(_deepLinkSubscription?.cancel() ?? Future<void>.value());
67    super.dispose();
68  }
69
70  Future<void> _loadStartupAttribution() async {
71    final initialDeepLink = await attriax.deepLinks.waitForInitialDeepLink();
72    final installReferrer = await attriax.installReferrer;
73
74    if (!mounted) {
75      return;
76    }
77
78    if (installReferrer != null) {
79      debugPrint('Install referrer: ${installReferrer.campaign}');
80    }
81
82    final resolution = initialDeepLink?.resolution;
83    if (resolution != null) {
84      _openDeepLink(resolution.deepLink);
85    }
86  }
87
88  Future<void> _handleDeepLinkEvent(AttriaxDeepLinkEvent event) async {
89    final result = await event.resolve();
90    final resolution = result.resolution;
91    if (!mounted || resolution == null) {
92      return;
93    }
94
95    _openDeepLink(resolution.deepLink);
96  }
97
98  void _openDeepLink(AttriaxDeepLink deepLink) {
99    final routeName = deepLink.path.startsWith('promo/')
100        ? '/promo'
101        : '/deep-link';
102
103    navigatorKey.currentState?.pushNamed(routeName, arguments: deepLink);
104  }
105
106  
107  Widget build(BuildContext context) {
108    return const Scaffold(body: Center(child: Text('Attriax ready')));
109  }
110}
111
112class PromoScreen extends StatelessWidget {
113  const PromoScreen({super.key});
114
115  
116  Widget build(BuildContext context) {
117    return const Scaffold(body: Center(child: Text('Promo screen')));
118  }
119}
120
121class DeepLinkScreen extends StatelessWidget {
122  const DeepLinkScreen({super.key});
123
124  
125  Widget build(BuildContext context) {
126    return const Scaffold(body: Center(child: Text('Deep link screen')));
127  }
128}