Skip to main content

SDK Usage

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.

DetourConfig.linkProcessingMode controls link sources:

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

DetourResult and routing fields

DetourResult contains:

  • processed
  • link (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).