SDK Usage
Recommended integration with DetourService
DetourService is the recommended orchestration layer. It:
- configures native bridge once,
- merges initial and runtime link handling into one pending intent queue,
- exposes startup readiness via
isInitialLinkProcessed, - uses explicit consume semantics (
consumePendingIntent()), - suppresses short-window duplicate emissions.
import 'package:detour_flutter_plugin/detour_flutter_plugin.dart';
import 'package:flutter/material.dart';
class MyApp extends StatefulWidget {
const MyApp({super.key});
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final detour = DetourService();
void initState() {
super.initState();
detour.addListener(_onDetourChanged);
_startDetour();
}
Future<void> _startDetour() async {
await detour.start(
const DetourConfig(
apiKey: '<REPLACE_WITH_YOUR_API_KEY>',
appID: '<REPLACE_WITH_APP_ID_FROM_PLATFORM>',
shouldUseClipboard: true,
linkProcessingMode: LinkProcessingMode.all,
),
);
}
void _onDetourChanged() {
final intent = detour.pendingIntent;
if (intent == null) return;
// Route once, then mark as consumed.
// context.go(intent.link.route);
detour.consumePendingIntent();
}
}
If you want complete, runnable integration, go to Examples.
Link processing mode
DetourConfig.linkProcessingMode controls link sources:
| Value | Universal/App links | Deferred links | Custom scheme links |
|---|---|---|---|
LinkProcessingMode.all (default) | Yes | Yes | Yes |
LinkProcessingMode.webOnly | Yes | Yes | No |
LinkProcessingMode.deferredOnly | No | Yes | No |
DetourResult and routing fields
DetourResult contains:
processedlink(DetourLink?)
If link != null, routing payload is:
link.route(path + query)link.pathname(path only)link.params(Map<String, String>)link.url(raw URL string)link.type(deferred | verified | scheme)
Manual processing
You can process arbitrary URLs explicitly:
final result = await detour.processLink(
'https://example.godetour.link/abc123?source=push',
);
if (result.link != null) {
// Navigate with result.link!.route
}
Use emitIntent: false when you need result inspection without pushing intent into service queue.
Low-level API (DetourFlutterPlugin)
If you need full manual control, use DetourFlutterPlugin directly:
final plugin = DetourFlutterPlugin();
await plugin.configure(
const DetourConfig(
apiKey: '<REPLACE_WITH_YOUR_API_KEY>',
appID: '<REPLACE_WITH_APP_ID_FROM_PLATFORM>',
),
);
final initial = await plugin.resolveInitialLink();
final stream = plugin.linkStream;
final processed = await plugin.processLink('https://example.godetour.link/path');
Analytics
Use predefined enum events only:
await detour.logEvent(
DetourEventName.purchase,
data: {'value': 9.99, 'currency': 'USD'},
);
await detour.logRetention('home_screen_viewed');
logEvent accepts DetourEventName (not arbitrary event strings).