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_flutterExample
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}