Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

George Ikwegbu Chinedu
George Ikwegbu Chinedu

Posted on • Edited on

     

Implementing App and Universal Links in Flutter

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

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>
Enter fullscreen modeExit fullscreen mode
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.
Enter fullscreen modeExit fullscreen mode

🍦 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
Enter fullscreen modeExit fullscreen mode

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"]}}]
Enter fullscreen modeExit fullscreen mode

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"]}}]
Enter fullscreen modeExit fullscreen mode

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
Enter fullscreen modeExit fullscreen mode

NB: It is very important that you placeassetlinks.json inside the.well-known/ directory.

NB: The domain must match what you provided in yourAndroidManifest.xmlandroid: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.

Accessible assetlink.json

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

Statement List Generator

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

Deep Link Get started
Getting Started

Complete File upload
Successful Upload

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.

Your flutter app settings
Your flutter app settings

Set as default
Set as default

Approved Hosts
Approved Hosts

✅ 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
Approved Hosts

Whoop Whoooop!!!! We just finished Applink on our Android.

Celebration Gif

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 inXCode,
  • In yourProject Navigator, click on theRunner.
  • Click theRunner in theTARGETS section.
  • SelectSigning & Capabilities.
  • Click on the+ Capability,
  • When theModal pops up, search forAssociated Domains and add it.

Getting to capabilities modal in XCode

Searching for the Associated Domain inside capabilities in XCode

After adding theAssociated Domains, update the currentweb credentialDomains with;

applinks:gikwegbu.com// first inputapplinks:www.gikwegbu.com// second input
Enter fullscreen modeExit fullscreen mode

NB: I like adding more options so my app will be recognized when users try to access it with or without thewww.

AppLinks values

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>
Enter fullscreen modeExit fullscreen mode

NB:gikwegbu.com should be your owndomain.

From ourStep 3 above, whilst still on theRunner in theTARGET section:

  • Click on theinfo tab.
  • Open theURL 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.

AppLinks values

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;
Enter fullscreen modeExit fullscreen mode
<key>FlutterDeepLinkingEnabled</key><true/>
Enter fullscreen modeExit fullscreen mode

📡 Creating & Hosting AASA file

Open yourproject root in theterminal and run the below code:

$touchapple-app-site-association
Enter fullscreen modeExit fullscreen mode

Then copy and paste the below code, with your owndata;

{"applinks":{"apps":[],"details":[{"appID":"[TEAM_ID].[APP_BUNDLE_ID]","paths":["[PATH_FOR_REDIRECTION]"]}]}}
Enter fullscreen modeExit fullscreen mode

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]>
Enter fullscreen modeExit fullscreen mode

]

Once you're done with the above, host the AASA file on your domain, within the.well-known/ directory, just like you did with yourAndroidassetlinks.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
Enter fullscreen modeExit fullscreen mode
NB: Since we haven't worked on the Routing system in our Flutter app, the above command should simply launch your app.
Enter fullscreen modeExit fullscreen mode

⛓️ 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 description

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);}}}
Enter fullscreen modeExit fullscreen mode

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

Congratulations

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)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
odinachi profile image
Odinachi David
Flutter & Dart Software Engineer
  • Joined

This was super helpful... Thank you.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Frontend Blockchain | Web | Mobile Dev
  • Location
    Lagos, Nigeria
  • Education
    B.Eng Computer Engineering
  • Work
    Co-Founder & CTO Alida School
  • Joined

More fromGeorge Ikwegbu Chinedu

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp