DeepLynks
DeepLynks (now URLynk) is a Flutter package for deep linking. It opens the app directly if it's installed, or redirects to the store for download if not, preserving the link context through installation.
Features
- Quick Integration: Minimal setup required to get started.
- Platform Support: Supports Android App Links and iOS Universal Links.
- Deferred Linking: Seamlessly redirect users to the store for downloads and preserve link even after installation.
- Optional account creation: Start creating unlimited deferred deep links for free — no account required.
🚀 New Feature: Branded Domains for Deep Links!
You can now use your own branded domain to generate deep links via our package (v2.0.0 onwards).
Enhance your brand visibility and user trust with custom domain support!
Installation
-
Add this package to your
pubspec.yaml:dependencies: deeplynks: <latest_version> -
Run
flutter pub getto install the package.
Platform Setup
Android
- Open
android/app/src/main/AndroidManifest.xml. - Add the following
<meta-data>tag and<intent-filter>inside the<activity>tag with.MainActivity.
Replace<app_id>with the unique app ID generated during the firstDeepLynks.init()call. (Check Usage section below.)
<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="http" android:host="urlynk.in" android:pathPrefix="/<app_id>/" />
<data android:scheme="https" android:host="urlynk.in" android:pathPrefix="/<app_id>/" />
<!-- If you have created links using older versions (below v3.0.0) -->
<data android:scheme="http" android:host="deeplynks.web.app" android:pathPrefix="/<app_id>/" />
<data android:scheme="https" android:host="deeplynks.web.app" android:pathPrefix="/<app_id>/" />
<!-- End -->
</intent-filter>
- Update
MainActivity.ktto handle deep links:
import android.net.Uri
import android.os.Bundle
import android.content.Intent
import io.flutter.plugin.common.MethodChannel
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() {
private val CHANNEL = "app.web.deeplynks"
private var initialLink: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
intent?.let {
if (Intent.ACTION_VIEW == it.action) {
initialLink = it.data.toString()
}
}
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "getInitialLink") {
result.success(initialLink)
initialLink = null
} else {
result.notImplemented()
}
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.data?.let {
flutterEngine?.dartExecutor?.binaryMessenger?.let { messenger ->
MethodChannel(messenger, CHANNEL).invokeMethod("onLink", it.toString())
}
}
}
}
- Test on Emulator
-
Run the app on emulator.
-
Execute this command on the terminal.
adb shell am start -a android.intent.action.VIEW -d "<created_deep_link>" <application_id>
- If successful, the app will launch & Deeplynks().stream will receive the link data.
iOS
1. Add FlutterDeepLinkingEnabled Key in Info.plist
<key>FlutterDeepLinkingEnabled</key>
<true/>
2. Add Associated Domains
- Open the
Runner.xcworkspacefile in Xcode. - Select the top-level
Runnerproject in the Navigator. - Go to the Signing & Capabilities tab.
- Click the + Capability button.
- Select Associated Domains.
- In the Associated Domains section, click the + button.
- Add this domain:
applinks:urlynk.in. - If you have created links using older versions (below v3.0.0), add this domain also:
applinks:deeplynks.web.app
3. Update AppDelegate.swift
Modify AppDelegate.swift to handle incoming deep links:
import UIKit
import Flutter
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// TODO: ADD THIS METHOD
override func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let flutterViewController = window?.rootViewController as? FlutterViewController {
let channel = FlutterMethodChannel(name: "app.web.deeplynks", binaryMessenger: flutterViewController.binaryMessenger)
channel.invokeMethod("onLink", arguments: url.absoluteString)
}
return true;
}
}
4. Test on Simulator
- Run the app on simulator.
- Close the app.
- Run this command on the terminal.
xcrun simctl openurl booted <created_deep_link>
- If successful, the app will launch & Deeplynks().stream will receive the link data.
Usage
1. Initialize DeepLynks
Initialize the service at the start of your app. This generates a unique app ID that persists unless the application ID or bundle ID changes.
final appId = await Deeplynks().init(
context: context,
metaData: MetaInfo(
name: 'Deeplynks Demo',
description: 'This app is a working demo for showcasing Deeplynks features',
),
androidInfo: AndroidInfo(
sha256: [],
applicationId: 'com.example.deeplynks',
),
iosInfo: IOSInfo(
teamId: '',
appStoreURL: '',
bundleId: 'com.example.deeplynks',
),
);
print(appId);
Arguments
| Argument | Type | Description |
|---|---|---|
context |
BuildContext |
The build context. |
metaData |
MetaInfo |
App meta data. Used for link preview. |
metaData.name |
String |
App name / title for link preview. |
metaData.description |
String |
App description for link preview. |
metaData.imageURL |
String |
Image for link preview, typically an App Logo. |
androidInfo |
AndroidInfo |
Android-specific configuration. |
androidInfo.sha256 |
List<String> |
List of release SHA-256 keys |
androidInfo.applicationId |
String |
The application ID (package name) of your app. |
iosInfo |
IOSInfo |
iOS-specific configuration. |
iosInfo.teamId |
String |
Your Apple Developer Team ID. |
iosInfo.appStoreURL |
String |
The App Store download URL for your app. |
iosInfo.bundleId |
String |
The bundle ID of your app. |
2. Listen to incoming deep link data
Deeplynks().stream.listen((data) {
print(data);
});
3. Create a Deep Link
Generate a deep link with your custom data (string format), which can include absolute URLs, relative URLs, query parameters, JSON objects, plain text, or any other format you want to retrieve later.
final link = await Deeplynks().createLink(jsonEncode({
'referredBy': '12345',
'referralCode': 'WELCOME50',
}));
print('Generated link: $link');
Additional information
Think you've found a bug, or would like to see a new feature? We'd love to hear about it! Visit the Issues section of the git repository.