Skip to content

Flutter SDK

The Flutter SDK (tolinku) provides event tracking, deferred deep linking, referrals, and in-app messages for Flutter 3.10+ and Dart 3.0+.

Add the package to your pubspec.yaml:

dependencies:
tolinku: ^0.1.0

Then run:

Terminal window
flutter pub get

The SDK depends on:

  • http for network requests
  • webview_flutter for rendering in-app messages
  • shared_preferences for dismiss/impression state persistence

Configure the SDK before runApp() or in your first widget’s initState:

import 'package:tolinku/tolinku.dart';
void main() {
Tolinku.configure(
apiKey: 'tolk_pub_your_key',
// baseUrl: 'https://your-app.tolinku.com', // optional
// debug: true, // optional
);
runApp(MyApp());
}

Access the singleton anywhere:

final tolinku = Tolinku.instance;
Tolinku.instance.setUserId('user_123');
// Clear on logout
Tolinku.instance.setUserId(null);
// Simple event
await Tolinku.instance.track('custom.app_open');
// Event with properties
await Tolinku.instance.track('custom.purchase', properties: {
'amount': '29.99',
'currency': 'USD',
});
// Force flush
await Tolinku.instance.flush();

Events are batched (10 events or 5-second timer). For lifecycle-aware flushing, implement WidgetsBindingObserver:

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
Tolinku.instance.flush();
}
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}

Track purchases, cart activity, and product events via ecommerce:

Tolinku.instance.setUserId('user_123');
// Track a purchase
await Tolinku.instance.ecommerce.purchase(
transactionId: 'order_456',
revenue: 49.99,
currency: 'USD',
items: [
TolinkuItem(itemId: 'sku_1', itemName: 'T-Shirt', price: 24.99, quantity: 2),
],
);
// Track product views and cart events
await Tolinku.instance.ecommerce.viewItem(
items: [TolinkuItem(itemId: 'sku_1', itemName: 'T-Shirt', price: 24.99)],
);
await Tolinku.instance.ecommerce.addToCart(
items: [TolinkuItem(itemId: 'sku_1', quantity: 1)],
);
await Tolinku.instance.ecommerce.beginCheckout();
// Search and ratings
await Tolinku.instance.ecommerce.search(searchTerm: 'shoes');
await Tolinku.instance.ecommerce.rate(itemId: 'sku_1', rating: 4.5, maxRating: 5);
// Force flush
await Tolinku.instance.ecommerce.flush();

Ecommerce events are batched (10 events or 5-second timer). The SDK manages cart IDs automatically via SharedPreferences, clearing them after purchase. For lifecycle-aware flushing, add Tolinku.instance.ecommerce.flush() to your WidgetsBindingObserver.didChangeAppLifecycleState handler alongside the regular flush.

Parse incoming deep link URLs:

final result = Tolinku.parseDeepLink('https://your-app.tolinku.com/merchant/abc123');
print(result.path); // "/merchant/abc123"
print(result.queryParams); // {}

Use Flutter’s uni_links or app_links package to listen for incoming URLs, then pass them to parseDeepLink.

Claim the original link destination after the user installs your app.

On Android, Tolinku appends a tolk_token parameter to the Play Store referrer string. After install, use the android_play_install_referrer package to read it:

import 'package:android_play_install_referrer/android_play_install_referrer.dart';
final referrerDetails = await InstallReferrer.referrer;
final referrer = referrerDetails.installReferrer; // e.g. "tolk_token=abc123"
final uri = Uri.parse('https://x?$referrer');
final token = uri.queryParameters['tolk_token'];
if (token != null) {
final link = await Tolinku.instance.deferred.claim(token: token);
if (link != null) {
// Navigate to link.deepLinkPath
}
}

On iOS, use fingerprint matching instead:

final link = await Tolinku.instance.deferred.claimBySignals(
appspaceId: 'your_appspace_id',
timezone: 'America/New_York',
language: 'en-US',
screenWidth: 390,
screenHeight: 844,
);
final referrals = Tolinku.instance.referrals;
// Create a referral code
final result = await referrals.create(userId: 'user_123', userName: 'Jane');
print(result.referralCode); // "ABC123"
print(result.referralUrl); // "https://myapp.tolinku.com/ref/ABC123"
// Look up a referral
final info = await referrals.get('ABC123');
// Link a referred user (status stays pending until reward milestone is reached)
await referrals.complete(
code: 'ABC123',
referredUserId: 'user_456',
);
// Update milestone (completes the referral if it matches the reward milestone)
await referrals.milestone(code: 'ABC123', milestone: 'first_purchase');
// Claim reward (after granting it in your system)
await referrals.claimReward(code: 'ABC123');
// Get leaderboard
final leaders = await referrals.leaderboard(limit: 10);

Display messages using the built-in WebView dialog:

await Tolinku.instance.messages.show(
context,
trigger: 'on_open',
onAction: (action) {
// Handle CTA action URL
},
onDismiss: () {
// Message dismissed
},
);

The SDK fetches active messages, filters out dismissed ones, and presents the highest-priority message in a full-screen WebView dialog.

await Tolinku.instance.dispose();

This flushes queued events, closes the HTTP client, and clears the singleton.