Skip to content
Dashboard

Usage

Section titled “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});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final detour = DetourService();
@override
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.

DetourConfig.linkProcessingMode controls link sources:

ValueUniversal/App linksDeferred linksCustom scheme links
LinkProcessingMode.all (default)YesYesYes
LinkProcessingMode.webOnlyYesYesNo
LinkProcessingMode.deferredOnlyNoYesNo

DetourResult contains:

processed
link
Type DetourLink?

If link != null, routing payload is:

link.route

Path + query.

link.pathname

Path only.

link.params
Type Map<String, String>
link.url

Raw URL string.

link.type
Type deferred | verified | scheme

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.

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');

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).