Deep links are integral to modern mobile app experiences, allowing seamless navigation to specific content. This guide explores the significance of deep links in Flutter, demystifies their components, and outlines setup procedures for Android and iOS platforms. Learn how to enhance user engagement and streamline navigation with deep linking in Flutter.
Deep links are revolutionizing the mobile app landscape, and Flutter is leading the charge. Imagine receiving a product link from a friend and effortlessly accessing the exact product within the app. This magic is made possible through deep linking.
In Flutter, deep links act as direct gateways to specific app content or features. They are particularly crucial for apps with shareable content, enabling seamless in-app experiences when users share links. From supporting marketing campaigns to providing content shortcuts, deep links play a vital role.
This comprehensive guide aims to demystify deep linking in Flutter, covering everything from native Android and iOS setup to navigation handling with GoRouter.
Deep links not only streamline navigation but also enhance user retention, boost engagement, and simplify content sharing. Whether you’re creating your first deep link or refining existing ones, this guide serves as the ultimate roadmap to deep linking success.
A deep link directs users to a specific destination within your app rather than a web page. Let’s dissect its components using an example:
URL: https://codewithandrea.com/articles/parse-json-dart/
Annotated Example: An example of a full URL with scheme, host, port, path, query parameters, and fragment.
Understanding the structure of a deep link is crucial for effective handling within your Flutter app. Crafting well-designed URLs ensures smooth integration and navigation.
Stay tuned for the Flutter implementation section of this guide, where we’ll delve into handling deep links effectively within your app.
Mobile apps can handle two types of deep links, each based on the scheme they utilize. Let’s delve into the specifics of each type:
Consider the custom-scheme URI as an example:
URI: yourScheme://your-domain.com
In Android, this is referred to as a deep link, while in the iOS ecosystem, it’s termed a custom URL scheme. This approach proves useful when you lack a domain but still desire the benefits of deep linking.
You have the liberty to select any custom scheme you prefer, provided you define it within your app. Setting it up is swift as uniqueness isn’t a concern.
Join Our Whatsapp Group
Join Telegram group
However, there’s a trade-off in security since any app could potentially hijack your custom scheme, attempting to open your links. Moreover, if a user lacks your app and clicks on a custom scheme link, they’ll encounter a dead end with an error message. Despite not being the optimal practice, its simplicity makes it convenient for quick tests.
These are the conventional web URLs we encounter daily:
URL: https://your-domain.com
Termed App Links on Android and Universal Links on iOS, this method offers the most secure means of integrating deep link support into your mobile app.
It mandates ownership of a domain and entails verification on both ends. You need to register your domain within the app code (manifest file on Android and Associated Domains on iOS) and verify your mobile application on the server side.
Through this synchronization, your app recognizes the domain, and the domain authenticates your app. This mutual verification guarantees the integrity and genuineness of the deep links, ensuring a secure deep-linking experience. 👍
Enough with the theory; let’s delve into the platform setup!
To enable deep linking on Android, follow these steps to adjust the AndroidManifest.xml file:
android/app/src/main/AndroidManifest.xml
file.Here’s a sample intent filter structure:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="yourDomain.com" />
</intent-filter>
If opting for a custom scheme like yourScheme://yourDomain.com
, use:
<data android:scheme="yourScheme" />
<data android:host="yourDomain.com" />
Without specifying paths, the app can open all URLs from your domain. For more control, define accepted paths with relevant path tags such as path
, pathPattern
, and pathPrefix
.
For HTTP/HTTPS links, ensure your domain recognizes your app as a trusted URL handler through server verification:
assetlinks.json
containing digital asset links associating your site with your app.[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example",
"sha256_cert_fingerprints":
["00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"]
}
}]
Replace "com.example"
with your app’s package name and update sha256_cert_fingerprints
with your app’s unique SHA256 fingerprint.
assetlinks.json
file on your website, accessible via https://yourdomain/.well-known/assetlinks.json
.You can generate your app’s SHA256 fingerprint using the keytool
command or find it in the Developer Console if your app is signed via Google Play Store.
To validate your deep links on Android, follow these steps using an Android emulator:
adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d https://yourDomain.com
For custom schemes:
adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d yourScheme://yourDomain.com
android/sdk/platform-tools
directory and included in your system’s path before executing the commands.If the app opens “inside” the source app (e.g., Gmail or WhatsApp) instead of its own window, add android:launchMode="singleTask"
within the <activity>
tag to address this issue.
Here’s an illustration of the app after being launched with a deep link from WhatsApp:
By following these steps, you can effectively test the functionality of deep links within your Android app.
The disambiguation dialog is a prompt displayed by Android when a user clicks a link that multiple apps could potentially open. It serves as a means for the system to inquire, “Which app should handle this?”
Encountering this dialog suggests that your deep link setup is nearly flawless, with only a minor glitch present. Commonly, the absence of android:autoVerify="true"
in your manifest file could trigger this dialog, emphasizing its crucial role in bypassing such prompts.
Additionally, discrepancies within your assetlinks.json file, particularly in fingerprints or package name typos, might contribute to this issue.
Rectifying these minor setbacks ensures a seamless user experience, allowing links to open directly in your app without triggering the disambiguation dialog.
During debugging phases, encountering this dialog is expected and normal. Since the app isn’t yet signed with the production key, it fails to match the fingerprint specified in assetlinks.json, leading to the prompt’s appearance.
By addressing these nuances, you can streamline the user journey, ensuring a hassle-free transition from links to app content, devoid of disambiguation interruptions.
ios/Runner.xcworkspace
in Xcode.Runner > Signing & Capabilities > + Capability > Associated Domains
.applinks:
when configuring associated domains.Join Our Whatsapp Group
Join Telegram group
Info.plist
file.+
button next to Information Property List
to add URL types
.URL Schemes
, replace yourScheme
with your desired custom scheme. Example snippet for Info.plist
: <key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>yourScheme</string>
</array>
<key>CFBundleURLName</key>
<string>yourIdentifier</string>
</dict>
</array>
apple-app-site-association
without a file extension. {
"applinks": {
"apps": [],
"details": [
{
"appIDs": ["TeamID.BundleID"],
"components": [
{ "/": "/login", "comment": "Matches URL with a path /login" },
{ "/": "/product/*", "comment": "Matches any URL with a path that starts with /product/." },
{ "/": "/secret", "exclude": true, "comment": "Matches URL with a path /secret and instructs the system not to open it as a universal link." }
]
}
]
}
}
apple-app-site-association
file to your website’s .well-known
directory.https://yourDomain.com/.well-known/apple-app-site-association
.application/json
content type. xcrun simctl openurl booted https://yourDomain.com/path
For custom scheme links:
xcrun simctl openurl booted yourScheme://yourDomain.com/path
apple-app-site-association
file for HTTP/HTTPS links to function properly. If unavailable, consider implementing custom scheme links for testing purposes.Join Our Whatsapp Group
Join Telegram group
With the native setup complete, your app is ready to respond to deep links on iOS. Next, ensure seamless navigation to desired content within the app. Flutter’s GoRouter provides an effective solution for managing routes and handling deep links, facilitating a smoother user experience.
In honor of the International Day of Family Remittances (IDFR) 2024, Flutterwave, Africa's leading payment…
PadhAI, a groundbreaking AI app, has stunned the education world by scoring 170 out of…
Vector databases are essential for managing high-dimensional data efficiently, making them crucial in fields like…
Welcome to the whimsical world of Flutter app development services! From crafting sleek, cross-platform applications…
Flutter, Google's UI toolkit, has revolutionized app development by enabling developers to build natively compiled…
SQL (Structured Query Language) is a powerful tool for managing and manipulating databases. From converting…