Flutter Examples – Deep Linking: The Ultimate Guide

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.

Table of Contents

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.

Demystifying Deep Linking in Flutter

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/

  • Scheme: The protocol used to fetch the resource (e.g., http or https).
  • Host: The domain name indicating where the resource resides (e.g., codewithandrea.com).
  • Path: Identifies the specific resource within the host (e.g., /articles/parse-json-dart/).

Additional Components

  • Query Parameters: Extra options appended after a ? mark, often used for sorting or filtering data.
  • Port: Specifies the server’s network service port, commonly seen in development setups.
  • Fragment: Optional component following a # mark, focusing on a specific part of a webpage.

Example URL Structure

Annotated Example: An example of a full URL with scheme, host, port, path, query parameters, and fragment.

full-url

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.

Implementation Considerations

Stay tuned for the Flutter implementation section of this guide, where we’ll delve into handling deep links effectively within your app.

Introduction

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:

deep links web links

Custom Schemes

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.

HTTP/HTTPS Scheme

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

Implementation Setup

Enough with the theory; let’s delve into the platform setup!

Modifying AndroidManifest.xml

To enable deep linking on Android, follow these steps to adjust the AndroidManifest.xml file:

  1. Navigate to the File: Open the android/app/src/main/AndroidManifest.xml file.
  2. Add Intent Filter: Insert an intent filter within your activity tag.
  3. Specify Scheme and Host: Define your scheme and host within the data tags.

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.

Android Server Verification

For HTTP/HTTPS links, ensure your domain recognizes your app as a trusted URL handler through server verification:

  1. Create assetlinks.json: Craft a file named 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.

  1. Upload assetlinks.json: Place the assetlinks.json file on your website, accessible via https://yourdomain/.well-known/assetlinks.json.
  2. Verify Setup: Utilize Google’s statement list tester tool at Google Asset Links Tester to ensure correct configuration.

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.

google play app signing

Testing Procedure

To validate your deep links on Android, follow these steps using an Android emulator:

  1. Launch Emulator: Start an Android emulator on your development machine.
  2. Open Terminal: Access the terminal or command prompt.
  3. Execute Commands: Run the appropriate command based on the type of deep link you want to test. For HTTP/HTTPS links:
   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

Additional Considerations

  • ADB Location: Ensure that the Android Debug Bridge (ADB) is located in the android/sdk/platform-tools directory and included in your system’s path before executing the commands.
  • Multiple Devices/Emulators: If encountering an “adb: more than one device/emulator” error due to multiple Android devices or emulators, refer to relevant resources for resolution.
  • Alternative Testing Method: Another approach is to send the deep link to yourself using a messaging app (e.g., WhatsApp) and tapping on it to trigger the app. The goal at this stage is to verify that the app responds accordingly.

Potential Issue Resolution

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.

Example

Here’s an illustration of the app after being launched with a deep link from WhatsApp:

app inside app

By following these steps, you can effectively test the functionality of deep links within your Android app.

Understanding the Disambiguation Dialog on Android

Overview

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?”

disambiguation dialog

Significance

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.

Resolution

Rectifying these minor setbacks ensures a seamless user experience, allowing links to open directly in your app without triggering the disambiguation dialog.

Debugging Consideration

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.

Associated Domains Configuration

  1. Launch Xcode: Open ios/Runner.xcworkspace in Xcode.
  2. Access Capabilities: Navigate to Runner > Signing & Capabilities > + Capability > Associated Domains.
  3. Prefix Domain: Add your domain with the prefix applinks: when configuring associated domains.

Join Our Whatsapp Group

Join Telegram group

Custom Scheme Configuration

  1. Modify Info.plist: Open the Info.plist file.
  2. Add URL Types: Click the + button next to Information Property List to add URL types.
  3. Configure URL Schemes: Under 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>

iOS Server Verification

  1. Create apple-app-site-association File: Generate a file named apple-app-site-association without a file extension.
  2. Configure Digital Asset Links: Populate the file with configurations linking your website and app. Include supported paths. Example configuration:
   {
     "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." }
           ]
         }
       ]
     }
   }
  1. Host File on Website: Upload the apple-app-site-association file to your website’s .well-known directory.
  • Accessible via https://yourDomain.com/.well-known/apple-app-site-association.
  • Ensure the file is served with the application/json content type.
  • Avoid signing or encrypting the file.
  • Tap on the deep link URL to test.
  • Alternatively, use the terminal with the following commands: For HTTP/HTTPS links:
  xcrun simctl openurl booted https://yourDomain.com/path

For custom scheme links:

  xcrun simctl openurl booted yourScheme://yourDomain.com/path
  • Note: iOS requires the apple-app-site-association file for HTTP/HTTPS links to function properly. If unavailable, consider implementing custom scheme links for testing purposes.

  • Deep links are URLs that direct users to specific content within a mobile app. They are crucial in Flutter for providing seamless in-app experiences, enhancing user engagement, and simplifying content sharing.
  • Deep links consist of several components, including the scheme (e.g., http or https), host (domain name), path (specific resource), query parameters (extra options), port (server network port), and fragment (optional part of a webpage).
  • Mobile apps support custom scheme URIs and HTTP/HTTPS URLs. Custom schemes are simpler to set up but less secure, while HTTP/HTTPS links offer greater security but require domain ownership and server verification.
  • To set up deep links on Android, you need to modify the AndroidManifest.xml file to include intent filters specifying the scheme and host of your deep links. Additionally, you’ll need to verify your app’s association with your domain using an assetlinks.json file.
  • You can test deep links on Android by launching an emulator, opening a terminal or command prompt, and executing commands to simulate opening deep links using adb. You can test both HTTP/HTTPS links and custom scheme links using appropriate commands.
  • The disambiguation dialog appears when multiple apps on a device can handle a deep link. It indicates that your deep link setup is nearly complete but may require adjustments to bypass the dialog.
  • To configure deep links for iOS, you need to set up associated domains in Xcode and define custom URL schemes in the Info.plist file. Additionally, you’ll need to create an apple-app-site-association file on your server and ensure it’s accessible via HTTPS.
  • You can test deep links on iOS by tapping on the deep link URL directly or using the terminal with commands similar to those used for Android. Ensure that the apple-app-site-association file is properly configured on your server for HTTP/HTTPS links to function correctly.
  • Flutter’s GoRouter provides an effective solution for managing routes and handling deep links within Flutter apps. It facilitates smoother user experiences by seamlessly navigating users to desired content within the app.
  • Additional considerations include understanding the structure of deep links, ensuring proper configuration for both Android and iOS, and testing deep links thoroughly on various devices and environments to ensure a seamless user experience.

Join Our Whatsapp Group

Join Telegram group

Conclusion

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.

Leave a Reply

Unlocking Potential with Apple Vision Pro Labs Navigating 2023’s Top Mobile App Development Platforms Flutter 3.16: Revolutionizing App Development 6 Popular iOS App Development Languages in 2023 Introducing Workflow Apps: Your Flutter App Development Partner