Deep linking
Learn how to implement deep links into your iOS or Android app using Flutter. If you’d like to check out a sample app, see GitHub: Braze Flutter SDK Example. For general information about deep linking, see our Deep Linking FAQ.
Prerequisites
Before you can implement deep linking into your Flutter app, you’ll need to set up deep linking in the native Android or iOS layer.
Implementing deep linking
Step 1: Set up Flutter’s built-in handling
- In your Xcode project, open your
Info.plist
file. - Add a new key-value pair.
- Set the key to
FlutterDeepLinkingEnabled
. - Set the type to
Boolean
. - Set the value to
YES
.
- In your Android Studio project, open your
AndroidManifest.xml
file. - Locate
.MainActivity
in youractivity
tags. - Within the
activity
tag, add the followingmeta-data
tag:1
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
Step 2: Forward data to the Dart layer (optional)
You can use native, first-party, or third-party link handling for complex use cases, such as sending a user to a specific location in your app, or calling a specific function.
Example: Deep linking to an alert dialog
While the following example does not rely on additional packages, you can use a similar approach to implement native, first-party, or third-party packages, such as go_router
. Additional Dart code may be required.
First, a method channel is used in the native layer to forward the deep link’s URL string data to the Dart layer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
extension AppDelegate {
// Delegate method for handling custom scheme links.
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
forwardURL(url)
return true
}
// Delegate method for handling universal links.
override func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else {
return false
}
forwardURL(url)
return true
}
private func forwardURL(_ url: URL) {
guard let controller: FlutterViewController = window?.rootViewController as? FlutterViewController else { return }
let deepLinkChannel = FlutterMethodChannel(name: "deepLinkChannel", binaryMessenger: controller.binaryMessenger)
deepLinkChannel.invokeMethod("receiveDeepLink", arguments: url.absoluteString)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MainActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleDeepLink(intent)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleDeepLink(intent)
}
private fun handleDeepLink(intent: Intent) {
val binaryMessenger = flutterEngine?.dartExecutor?.binaryMessenger
if (intent?.action == Intent.ACTION_VIEW && binaryMessenger != null) {
MethodChannel(binaryMessenger, "deepLinkChannel")
.invokeMethod("receivedDeepLink", intent?.data.toString())
}
}
}
Next, a callback function is used in the Dart layer to display an alert dialogue using the URL string data sent previously.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
MethodChannel('deepLinkChannel').setMethodCallHandler((call) async {
deepLinkAlert(call.arguments, context);
});
void deepLinkAlert(String link, BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Deep Link Alert"),
content: Text("Opened with deep link: $link"),
actions: <Widget>[
TextButton(
child: Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}