flutter_linkme_sdk 0.3.0
flutter_linkme_sdk: ^0.3.0 copied to clipboard
Flutter SDK for LinkMe — short links, custom domains, multi-platform deep linking, and attribution analytics.
LinkMe Flutter SDK #
Cross-platform deep linking, deferred deep linking, and attribution for Flutter apps.
Quick start #
1. Prerequisites #
- A LinkMe app configured with your iOS bundle ID and Android package name
- API keys (
appIdandappKey) from App Settings > API Keys - Flutter 3.44+ (Swift Package Manager is enabled by default)
2. Install #
flutter pub add flutter_linkme_sdk
Or add manually to pubspec.yaml:
dependencies:
flutter_linkme_sdk: ^0.3.0
3. Configure native platforms #
iOS — Set the Runner deployment target to iOS 14 or newer, then enable Associated Domains on the Runner target:
applinks:links.yourco.com
Add a custom URL scheme in Info.plist (CFBundleURLSchemes): yourapp
Android — In android/app/src/main/AndroidManifest.xml, add intent filters:
<!-- HTTPS App Links -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="links.yourco.com" />
</intent-filter>
<!-- Custom scheme -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="yourapp" />
</intent-filter>
4. Initialize and handle links #
import 'package:flutter/material.dart';
import 'package:flutter_linkme_sdk/flutter_linkme_sdk.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await LinkMe.shared.configure(
const LinkMeConfig(
appId: String.fromEnvironment('LINKME_APP_ID'),
appKey: String.fromEnvironment('LINKME_APP_KEY'),
),
);
// Cold-start link
final initial = await LinkMe.shared.getInitialLink();
// Deferred deep link (first install)
final deferred = initial ?? await LinkMe.shared.claimDeferredIfAvailable();
runApp(App(initialPayload: initial, deferredPayload: deferred));
}
class App extends StatefulWidget {
const App({super.key, this.initialPayload, this.deferredPayload});
final LinkMePayload? initialPayload;
final LinkMePayload? deferredPayload;
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
late final StreamSubscription<LinkMePayload> _sub;
@override
void initState() {
super.initState();
// Live links while app is running
_sub = LinkMe.shared.onLink.listen(routeUser);
}
@override
void dispose() {
_sub.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(home: HomeScreen());
}
void routeUser(LinkMePayload payload) {
// Navigate based on payload.path / payload.params
}
}
Deferred deep linking #
| Platform | Primary | Fallback |
|---|---|---|
| iOS | Pasteboard (cid token) |
Fingerprint (/api/deferred/claim) |
| Android | Play Install Referrer (/api/install-referrer) |
Fingerprint (/api/deferred/claim) |
Enable Pasteboard for Deferred Links in App Settings for deterministic iOS attribution.
Swift Package Manager #
Flutter discovers the plugin's Swift packages from ios/flutter_linkme_sdk/Package.swift and
macos/flutter_linkme_sdk/Package.swift. Flutter 3.44+ generates the FlutterFramework
package sibling automatically, and the plugin resolves LinkMeKit 0.2.14 from its repository-root
Swift package. CocoaPods remains available for projects that have not migrated to SwiftPM.
Forced web redirects #
If a payload contains forceRedirectWeb: true and a non-empty webFallbackUrl, the SDK opens the external browser automatically and does not deliver that payload to getInitialLink(), claimDeferredIfAvailable(), or onLink.
API reference #
| Method | Description |
|---|---|
configure(config) |
Initialize the SDK |
getInitialLink() |
Get the payload that launched the app |
onLink (Stream) |
Stream of payloads while the app is running |
claimDeferredIfAvailable() |
Claim deferred deep link on first install |
track(event, {properties}) |
Send analytics events |
setUserId(userId) |
Associate a user ID |
setAdvertisingConsent(granted) |
Toggle Ad ID inclusion |
setReady() |
Signal readiness to process queued links |
debugVisitUrl(url, {headers}) |
Debug helper for testing link resolution |
Config options #
| Field | Type | Default | Description |
|---|---|---|---|
appId |
String? |
— | App identifier |
appKey |
String? |
— | Optional read-only key |
sendDeviceInfo |
bool |
true |
Include device metadata |
includeVendorId |
bool |
true |
Include vendor identifier |
includeAdvertisingId |
bool |
false |
Include Ad ID (requires consent) |
debug |
bool |
false |
Enable verbose native logs |
Instance-based client #
final client = LinkMeClient();
await client.configure(const LinkMeConfig(appId: 'app_123'));
Use LinkMeClient for dependency injection or test-friendly patterns. It mirrors the LinkMe API.
Example app #
The example/ directory contains a runnable sample:
cd example
cp .env.example .env # fill in your keys
flutter run
Troubleshooting #
- See the Android Troubleshooting guide for App Links verification issues.
- Enable
debug: trueinLinkMeConfigto see native logs for link resolution and deferred claims.
License #
Apache-2.0