It's no news that, comeAugust 25, 2025
,Firebase
will no longer supportdynamic links
for Flutter applications. To that effect, we will need to handle the app link (for Android) and the universal link (for iOS) ourselves. And in this article, we will be doing so with the help of onGenerateRoute.
Table of Content
- 🎉Introduction
- ✨AppLink Overview
- ⚙️Updating AndroidManifest.xml
- 🍦Creating SHA256
- 💪Creating & Hosting assetlinks.json file
- 🧪Testing and Confirming assetlinks.json
- 🚀Deploy app to PlayStore internal testing
✅Confirm the link is auto verified in the device hardware app settings
👮🏾♀️Adding capability
⛓️OnGenerateRoute Setup and Routing to a dynamic page with data
🎉 Introduction
Deep or dynamic linking is a great feature that Flutter offers in its application to enable a continuance in data consumption from a website to a mobile application.
For instance, say you have an e-commerce website with products to be sold or an online campaign website where users need to vote or be voted for. A user could share a link to that product/profile with another user, who then clicks on the link to be led to the website to continue their business. In a situation where you have both a website and a mobile app and you want the users to still continue their business through the mobile interface, that is where a deep or dynamic link comes in.
NB: In situations where the shared user does not have the app installed, they'd be redirected to their respective device's stores (Play or Apple Store) to download and continue with the application.
PS: In this article, we will be handling theapplink
anduniversal link
for Android and iOS, respectively.
✨ AppLink Overview
We will be following the officialAndroid Guidelines.
⚙️ Updating AndroidManifest.xml
Navigate to yourAndroidManifest.xml
file and add the below intent inside your<android>
block.
<meta-dataandroid:name="flutter_deeplinking_enabled"android:value="true"/><intent-filterandroid:autoVerify="true"><actionandroid:name="android.intent.action.VIEW"/><categoryandroid:name="android.intent.category.DEFAULT"/><categoryandroid:name="android.intent.category.BROWSABLE"/><dataandroid:scheme="https"/><dataandroid:scheme="http"/><dataandroid:host="gikwegbu.com"/><dataandroid:host="www.gikwegbu.com"/></intent-filter>
NB: You need `flutter_deeplinking_enabled` for it to work; that way, the route can be passed from the Android routing system into our Flutter application.NB: Please update the `gikwegbu` host with your personal domain name.
🍦 Creating SHA256
We will need to create anSHA256
for our application. To do that, open yourroot
project in theterminal
and run the below code:
keytool-list-v-keystore~/.android/debug.keystore-aliasandroiddebugkey-storepassandroid-keypassandroid
Then copy theSHA256
value that comes up.
💪 Creating & Hosting AssetLink.json file
You can either use theStatement List Generator and Tester link toGenerate your statement
and in future,Test your statement
. Or simply update the below json file with your own details;
NB: This codeMUST
be saved in theassetLinks.json
file.
[{"relation":["delegate_permission/common.handle_all_urls"],"target":{"namespace":"android_app","package_name":"com.gikwegbu.app","sha256_cert_fingerprints":["PASTE YOUR OWN SHA256 HERE"]}}]
NB: Update thepackage_name
with your app's own.
Congratulations if you've gotten to this place so far; you're a genius. But before we host ourjson
file, we need to do something first. I assume you already have aPlayStore
account and anAPP
created for your currently built application. If you don't, please pause and do so.
There is every tendency that your app already exists in the store, and you just want to include this feature, which is perfect. All I need you to do is get theSHA256
google Auto-created for you application in theintegrity
section of the console and update thesha256_cert_fingerprints
in yourAssetLink.json
. Remember, it's an array ofSHA256
values, so just acomma
and the newSHA256
value fromPlayStore console
.
[{"relation":["delegate_permission/common.handle_all_urls"],"target":{"namespace":"android_app","package_name":"com.gikwegbu.app","sha256_cert_fingerprints":["PASTE YOUR OWN SHA256 HERE","PASTE GOOGLE PLAY CONSOLE SHA256 HERE TOO"]}}]
Hosting your AssetLink.json file;
For this, you will have to reach out to the person managing the website, as we need to upload our file to a specific directory.
http://gikwegbu.com/.well-known/assetlinks.json
NB: It is very important that you placeassetlinks.json
inside the.well-known/
directory.
NB: The domain must match what you provided in yourAndroidManifest.xml
android:host
data as well.
NB: Once it has been hosted, make sure it's accessible by visitinghttp://gikwegbu.com/.well-known/assetlinks.json
. If it's accessible, you'll see thejson
data displayed.
🧪 Testing and Confirming AssetLink.json file
To test if yourassetlink.json
will be OK, provide the required details in theStatement List Generator and Tester, then click onTest Statement
to confirm.
This will crawl your website, to confirm theassetlink.json
file is present, and theSHA256
keys are also valid.
As a bonus, try inputing theSHA256
you got from theGoogle Play Console
, to confirm it works too.
🚀 Deploy app to PlayStore internal testing
Based on my earlier assumption that you just created the app on yourGoogle Console
, we would be deploying tointernal testing
, just so we could test out ourdeep links
before releasing them to the actual store.
NB: This article won't cover how to build and upload yourappbundle
to the store.
PS: If you have already released your app, no problem, just continue with the next step.
On yourGoogle Play Console
, go to theDeep Links
onSide Navigation
, If everything we've done so far has worked out well, you should get a pretty dashboard like below.
NB: If there's still an issue, please reach out to me, and I'll be glad to help out.
NB: Once you have uploaded theappbundle
to your internal testing, wait for a while (say an hour; honestly, I don't know how long it takes for Google to verify your assetlink and web domains) before installing it.
NB: When you have installed it on your device, go to yourflutter app's
details, selectSet as default
, >Supported web addresses
and see if thehost
you provided in theAndroidManifest.xml
is/are present there.
✅ Confirm the link is auto verified in the device hardware app settings
Because in ourAndroidManifest.xml
, we set the<intent-filter android:autoVerify="true">
, therefore, you shouldn't see thetoggle/switch
button beside yourhost
.
Approved Hosts
Whoop Whoooop!!!! We just finished Applink on our Android.
PS: Stick around to the end of the article to learn how the routing works with theonGenerateRoute
configs inFlutter
.
🌐 Universal Link Overview
For our iOS application, we will be using aUniversal link
, which is an exclusive type of deep link to Apple devices that uses either thehttp
or thehttps
schemes.
👮🏾♀️ Adding capability
In the next few steps, we will be working closely withXCode
via the following steps:
- Open your project in
XCode
, - In your
Project Navigator
, click on theRunner
. - Click the
Runner
in theTARGETS
section. - Select
Signing & Capabilities
. - Click on the
+ Capability
, - When the
Modal
pops up, search forAssociated Domains
and add it.
After adding theAssociated Domains
, update the currentweb credential
Domains
with;
applinks:gikwegbu.com// first inputapplinks:www.gikwegbu.com// second input
NB: I like adding more options so my app will be recognized when users try to access it with or without thewww
.
NB: While the above is the easiest and UI approach of adding theRunner.entitlements
to your app, you could just create. aRunner.entitlements
file within yourios/Runner/
directory, ad add the below code manually:
<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEplistPUBLIC"-//Apple//DTD PLIST 1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plistversion="1.0"><dict><key>com.apple.developer.associated-domains</key><array><string>applinks:gikwegbu.com</string><string>applinks:www.gikwegbu.com</string></array></dict></plist>
NB:gikwegbu.com
should be your owndomain
.
From ourStep 3
above, whilst still on theRunner
in theTARGET
section:
- Click on the
info
tab. - Open the
URL Types
dropdown and complete the form with below data:
identifier
: your app's bundle Identifier,URL Schemes
: https.
NB: You can get youbundle Identifier
from yourSigning & Capabilities
tab inXCode
.
NB: For the iOS routing system to successfully parse the dynamic url back into our Flutter application, we need to add the below data into our info.plist file;
<key>FlutterDeepLinkingEnabled</key><true/>
📡 Creating & Hosting AASA file
Open yourproject root
in theterminal
and run the below code:
$touchapple-app-site-association
Then copy and paste the below code, with your owndata
;
{"applinks":{"apps":[],"details":[{"appID":"[TEAM_ID].[APP_BUNDLE_ID]","paths":["[PATH_FOR_REDIRECTION]"]}]}}
NB: To get yourTeam_ID
, just open yourapple dev account, you'd see the ID by thetop right
,underneath your name
of your screen,
"paths": [ "/your_path", // Users will be be redirected if they visit <https://gikwegbu.com/your_path> "/your_path/*", // Users will be redirected if they visit <https://gikwegbu.com/your_path/[shduewjakssd]> "*", // will be redirected to any link <https://gikwegbu.com/[wild card links]> "NOT /your_path", // Users will be be redirected to any link other than <https://gikwegbu.com/your_path> "NOT /your_path/*", // Users be redirected to any link other than <https://gikwegbu.com/your_path/[wild card]>
]
Once you're done with the above, host the AASA file on your domain, within the.well-known/
directory, just like you did with yourAndroid
assetlinks.json
file.
🔌 Confirming Our AASA file
To confirm if the AASA file was properly hosted, once you visit thehttp://gikwegbu.com/.well-known/apple-app-site-association
, the file will automatically be downloaded onto your machine.
NB:gikwegbu
will be your own domain.
⚒️ Testing Via cmd xcrun
First make sure yourXCode
is running yourFlutter app
, Open yourterminal
and run the below code:
$xcrunsimctlopenurlbootedhttps://gikwegbu.com/guest/dsewe
NB: Since we haven't worked on the Routing system in our Flutter app, the above command should simply launch your app.
⛓️ OnGenerateRoute Setup and Routing to a dynamic page with data
For an efficient and cleaner codebase, I like to keep all my routes in a separate file.
Within yourMaterialApp
, in yourmain.dart
file, you can add youronGenerateRoute
data and point it to the externalroutes
file.
Image of the main.dart file
Here, we will create a class calledRoutes
;
classRoutes{staticRoute<dynamic>generateRoute(RouteSettingssettings){debugPrint('${settings.name} Is the current route');if(settings.name!.contains('guest')){finalpage=PreInviteInfoScreen(code:settings.name!.split('/').last,);returnMaterialPageRoute(builder:(_)=>page);}finalargs=settings.arguments;// For screens that requires arguements to be passedswitch(settings.name){caseHomeView.routeName:constpage=HomeView();returnMaterialPageRoute(builder:(_)=>page);default:constpage=HomeView();returnMaterialPageRoute(builder:(_)=>page);}}}
NB: For more context, say the link our users clicks on ishttps://www.gikwegbu.com/guest/Uhdys
, theif statement
, will check if that route has theguest
keyword, then extract to get the code as it aURL PATH
.
This way, when a user clicks on the link above, only theUhdys
is now being passed as theargument
for the next screen immediately the app launches.
THE END
So with the above sets of instructions and examples, you should be able to get the Applink and Universal link ready for your FLutter application. CONGRATULATIONS AND GOOD LUCK.
Top comments(1)
For further actions, you may consider blocking this person and/orreporting abuse