DeepLinking Flutter

Gaurav Swarankar
4 min readApr 16, 2024

Hello Medium readers. Today We are going to discuss on deep linking in fluter. Flutter supports deep linking on iOS, Android, and web browsers. Opening a URL displays that screen in your app.

Deeplink is a link that sends users to a destination in your app rather than a web page.

Working of deep linking:

When we taps a link, it triggers a URL-based transition.

When application is not installed on your smartphone, the transition will be directed to either Google Play or App Store, depending on the operating system of your mobile device: Android or iOS.

Deeplink contains:

  1. Schema : This is the first part of link. (http or https)
  2. Host : Domain name of the link
  3. Path : Path that user wants to access.

However we will also see Query parameters (?) in our url . Query parameters are helpful to sort or filter data.

In deep linking application may already be open when the link is clicked this means we need to handle link clicks in the background of a running application. Let’s see how to do this best in Flutter. It’s necessary to configure appropriate permissions for the deep linking. Permissions are configured in exactly the same way as the corresponding native configurations. For Android (Manifest.xml ) For Ios (Info.plist)

Benefits of Deep Linking:

  1. seamless UX
  2. Increase Traffic

Setting up Deep Links on Android

Let’s see step by step how can we implement deep linking in flutter.

  1. Let’s open Android Manifest file android/app/src/main/AndroidManifest.xml.
  2. Add a meta-data tag to the main activity to configure the Flutter framework for handling deep links. we are trying to configure url => https://deeplink-demo-site.vercel.app
<meta-data 
android:name="flutter_deeplinking_enabled"
android:value="true"
/>
<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="deeplink-demo-site.vercel.app" />
</intent-filter>

If you have custom url like ( scheme://domain.com) Then add this in your manifest file :

<data android:scheme="scheme" />
<data android:host="Domain.com" />

3. Integrate data tags to specify the host component and URL scheme within the intent filter.

Setting up Deep Links on iOS

  1. We will Declare the scheme in ios/Runner/Info.plist to enable custom URL capabilities for iOS.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>https</string>
</array>
<key>CFBundleURLName</key>
<string>deeplink-demo-site.vercel.app</string>
</dict>
</array>
<key>FlutterDeepLinkingEnabled</key>
<true/>

Open URL in Flutter: Now, in your Flutter code, you can use the url_launcher package to open a URL:

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Deep Linking Example")),
body: Center(
child: RaisedButton(
onPressed: _launchURL,
child: Text('Open URL'),
),
),
),
);
}

_launchURL() async {
const url = 'your_scheme://your_host/path';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}

Replace your_scheme://your_host/path with your actual deep link URL.

With these configurations and code in place clicking the “Open URL” button will launch the URL specified on both Android and iOS devices. Make sure to handle the deep link in your app’s code accordingly.

Hurray we have opened url 🥳🥳

Wait…….. This is not end 😵😵

Now we will try to open url without using any third party lib. In the above code we are using url_launcher lib.

Let’s go step by step.

  1. We will setup first for android platform.
    open android >> app >> src >> main >> kotlin >> MainActivity.kt
package com.gaurav.deeplinking_flutter_platform_specific_code

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.EventChannel.EventSink
import io.flutter.plugin.common.MethodChannel
import android.net.Uri

class MainActivity: FlutterActivity() {

private val CHANNEL = "launchUrl"

override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)

MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "launchUrl")
.setMethodCallHandler { call, result ->
if (call.method == "openUrl") {
val url = call.arguments as String
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(intent)
result.success(null)
} else {
result.notImplemented()
}
}
}
}

2. For ios we will modify AppDelegate.swift file.

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "launchUrl", binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { (call, result) in
if call.method == "openUrl" {
if let url = call.arguments as? String {
if let url = URL(string: url) {
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
result(nil)
} else {
result(FlutterError(code: "UNAVAILABLE", message: "URL cannot be opened", details: nil))
}
} else {
result(FlutterError(code: "INVALID_URL", message: "Invalid URL", details: nil))
}
} else {
result(FlutterError(code: "INVALID_ARGUMENT", message: "Missing URL argument", details: nil))
}
} else {
result(FlutterMethodNotImplemented)
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

Now we can easily open Url in android and ios devices without using url_launcher lib. 🙂

I Have added a sample app on my github.
Feel free to check.

Hope you enjoyed this article!

Clap 👏 If this article helps you.

See you all again soon!

--

--