| j / k | Scroll down / up |
| gg | Scroll to top |
| G | Scroll to bottom |
| ⌘K / / | Open search |
| ? | Show this help |
| Esc | Close search / help |
| n / N | Next / previous section |
| h | Go to landing |
| d | Go to docs |
| : | Command mode — type section name |
Press ? or Esc to close
Incoming links — from the OS, another app, or a push notification — are resolved to a route by DeepLinkService and navigated after the first frame paints.
The service is started in App.initState and disposed in dispose. Navigation happens inside a post-frame callback so it never races with the initial route build.
@override
void initState() {
super.initState();
DeepLinkService.instance.init(
onResolved: (path) {
WidgetsBinding.instance.addPostFrameCallback((_) {
appRouter.go(path);
});
},
);
}
@override
void dispose() {
DeepLinkService.instance.dispose();
super.dispose();
} Links are matched by prefix and mapped to the corresponding AppRoutes path, including dynamic segments like a user id.
String _resolve(Uri uri) {
if (uri.path.startsWith('/feed')) return AppRoutes.feed.route;
if (uri.path.startsWith('/profile')) {
final id = uri.pathSegments.elementAt(1);
return AppRoutes.profileView.route.replaceFirst(':id', id);
}
if (uri.path.startsWith('/notifications')) return AppRoutes.notifications.route;
return AppRoutes.home.route;
} redirect guard as every other navigation.