Deep Linking in Flutter: A Complete Setup Guide
Technology Blogs

Deep Linking in Flutter: A Complete Setup Guide

Ajay Jadhav
Full Stack Developer
Table of Content

Deep linking helps users move from a URL to the exact screen they want inside your app. A password reset link that opens in a browser feels broken when the app is installed. A deep link fixes this. It opens your app and takes the user to the right place with no extra steps.

Flutter does not include deep linking by default. Instead, it depends on native systems: Android App Links and iOS Universal Links. Both are stable and supported. This guide shows how to set them up with the app_links package and how to host the required files on GitHub Pages.

1. What Deep Linking Is and Why It Matters

A deep link is a URL such as:

https://yourdomain.com/product/100

When a user taps this link, two things happen:

  1. The app opens instead of the browser.
  2. The app navigates to the matching screen, such as the Product Details page.

This creates a smooth experience and removes extra steps for the user.

2. Firebase Dynamic Links Are Deprecated

Firebase Dynamic Links was once a common choice. Google has deprecated it, and it will not receive new features or fixes. Google now recommends the native systems: App Links on Android and Universal Links on iOS. They are secure and do not rely on a third-party service.

Firebase Dynamic Links Are Deprecated

3. How App Links and Universal Links Work

Both systems need proof that your app owns and controls the domain. They check this by reading a file hosted on your domain:

Android expects:

https://yourdomain.com/.well-known/assetlinks.json

iOS expects:

https://yourdomain.com/apple-app-site-association

If the files are missing or invalid, the link opens in a browser.

4. Prerequisites and Package Installation

Before you start, have:

  • Flutter 3.x or newer
  • Your Android package name
  • Your iOS Bundle ID and Apple Team ID
  • A public HTTPS domain (GitHub Pages works well)

Install the package:

dependencies:

  app_links: ^6.4.1

Run:

flutter pub get

5. Android Setup

5.1 Add Intent Filters

In android/app/src/main/AndroidManifest.xml, add an intent filter inside your main activity:

<activity>

    <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" android:host="yourdomain.com" android:pathPrefix="/"/>

    </intent-filter>

</activity>

5.2 Create the assetlinks.json File

This file links your domain to your app:

[

  {

    "relation": ["delegate_permission/common.handle_all_urls"],

    "target": {

      "namespace": "android_app",

      "package_name": "com.example.app",

      "sha256_cert_fingerprints": [

        "YOUR_SHA256_FINGERPRINT"

      ]

    }

  }

]

Get the SHA256 fingerprint:

keytool -list -v \

-keystore ~/.android/debug.keystore \

-alias androiddebugkey \

-storepass android -keypass android

Use your release keystore for production builds.

6. iOS Setup

6.1 Enable Associated Domains

In Xcode:

  1. Open the project.
  2. Go to Signing & Capabilities.
  3. Add Associated Domains.
  4. Add:
applinks:yourdomain.com

Enable Associated Domains

6.2 Create the AASA File

The file has no extension:

{

  "applinks": {

    "apps": [],

    "details": [

      {

        "appID": "TEAMID.com.example.app",

        "paths": ["*"]

      }

    ]

  }

}

appID = AppleTeamID.BundleID

Explore Our Flutter Development Services for Scalable Mobile Apps

7. Hosting the Verification Files on GitHub Pages

GitHub Pages is free and supports HTTPS, which both platforms need.

Steps:

1. Create a new repository.

2. Add this structure:

/

  .nojekyll

  apple-app-site-association

  .well-known/

      assetlinks.json

.nojekyll ensures GitHub keeps the .well-known directory.

3. Enable GitHub Pages in Settings → Pages.

Your hosted files will be here:

Android:

https://yourusername.github.io/.well-known/assetlinks.json

iOS:

https://yourusername.github.io/apple-app-site-association

8. Handle the Deep Link in Flutter

Once the app launches, use the app_links package to read the incoming URL:

import 'package:app_links/app_links.dart';

import 'package:flutter/material.dart';

class DeepLinkService {

  final AppLinks _appLinks = AppLinks();

  void init(BuildContext context) {

    _handleInitialLink(context);

    _handleStreamLinks(context);

  }

  Future<void> _handleInitialLink(BuildContext context) async {

    final uri = await _appLinks.getInitialLink();

    if (uri != null) _navigate(uri, context);

  }

  void _handleStreamLinks(BuildContext context) {

    _appLinks.uriLinkStream.listen((uri) {

      if (uri != null) _navigate(uri, context);

    });

  }

  void _navigate(Uri uri, BuildContext context) {

    if (uri.path.contains("product")) {

      Navigator.pushNamed(

        context,

        "/product",

        arguments: uri.pathSegments.last,

      );

    } else {

      Navigator.pushNamed(context, "/home");

    }

  }

}

Call DeepLinkService().init(context); early in your app.

9. Test and Verify

Testing is essential because deep linking depends on correct hosting.

9.1 Online Validators

  • Google Digital Asset Links Validator- Checks your Android file.
  • AASA Validators- Confirm JSON structure and headers for iOS.

9.2 Android Studio App Links Assistant

Go to:

Tools → App Links Assistant

It checks your manifest and lets you test links on a device.

9.3 Manual Commands

Android:

Adb shell am start -a android.intent.action.VIEW -d "https://yourdomain.com/product/100" com.yourappid.app

iOS (Simulator):

xcrun simctl openurl booted https://yourdomain.com/product/100
coma

Conclusion

You now have a clean and reliable deep linking setup for Flutter. By using native systems on Android and iOS, you avoid third-party services and keep full control of routing and verification. This approach gives your app a direct and consistent path from a URL to the right screen.

Ajay Jadhav

Ajay Jadhav

Full Stack Developer

Ajay Jadhav is a Full Stack Developer with 3+ years of experience in building scalable mobile and web applications using Flutter and Spring Boot. He specializes in secure API development, AI features like OCR and image background removal, and automation using Fastlane. Ajay has successfully deployed 20+ mobile applications to both the App Store and Play Store, and is known for strong problem-solving skills and a continuous learning mindset.

Share This Blog

Read More Similar Blogs

Let’s Transform
Healthcare,
Together.

Partner with us to design, build, and scale digital solutions that drive better outcomes.

Location

5900 Balcones Dr, Ste 100-7286, Austin, TX 78731, United States

Contact form