Deep linking in Flutter
Flutter abstracts the platforms well until you reach deep links, where you are back to editing Info.plist and AndroidManifest.xml by hand.
6 August 2026 by PAD team
The Dart side
Packages like app_links give you both the initial URL and a stream of subsequent ones, which maps neatly onto cold and warm starts:
final appLinks = AppLinks();
final initial = await appLinks.getInitialAppLink();
if (initial != null) route(initial);
appLinks.uriLinkStream.listen(route);
With go_router, routing the URI is a one-liner. That part rarely causes trouble.
iOS, still by hand
Custom scheme in Info.plist, Associated Domains entitlement, and the apple-app-site-association file on your domain served with no redirect and no extension. Flutter does not generate any of this, and the failure is silent when any of it is wrong.
Android, still by hand
Intent filters in AndroidManifest.xml with autoVerify, and assetlinks.json on the domain with the right signing fingerprint. Check the state on a device rather than trusting the manifest:
adb shell pm get-app-links com.example.app
The gotcha specific to Flutter
Hot restart does not re-deliver the initial link, so a link that worked once during development appears to stop working. Kill the app properly between tests, or you will spend an afternoon debugging something that is not broken.
Where Flutter cannot help
A link tapped inside Instagram or Facebook never reaches your app, because the in-app browser stops before the operating system decides anything. Store links there end on a blank page, which is the same problem every framework shares.
One link for your marketing traffic that survives in-app browsers on both platforms.