Skip to content

Commit a600c10

Browse files
committed
add branch io docs
1 parent aedafab commit a600c10

File tree

2 files changed

+286
-14
lines changed

2 files changed

+286
-14
lines changed

docs/ff-concepts/navigation-routing/deep-dynamic-linking.md

Lines changed: 286 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,14 @@ In this step, You will set the URL scheme. To do that:
8484
enter the **scheme** **name** (before "://") and **hostname** (after "://").
8585

8686
4. If you want users to navigate back to the home page instead of closing the app when they press
87-
the back button from a deep link page, enable the **Pages Are Subroutes of Root Page** option. *
88-
*Tip**: we recommend enabling this option to increase user engagement with your app.
87+
the back button from a deep link page, enable the **Pages Are Subroutes of Root Page** option.
8988

9089
![img_3.png](imgs/img_3.png)
9190

91+
:::tip
92+
We recommend enabling this option to increase user engagement with your app
93+
:::
94+
9295
#### 2. Setting page URL
9396

9497
The page URL points to the specific page in your app, which is used on the Web and for deep linking
@@ -176,7 +179,7 @@ Here is how you do it:
176179
</figure>
177180
</details>
178181

179-
## Dynamic Link
182+
## Dynamic Links with Firebase Dynamic Links [Deprecated]
180183

181184
The dynamic link opens a specific page in your app. Unlike the deep link, the dynamic link survives
182185
the app install. That means if the user has not installed the app, they can be taken to the
@@ -193,10 +196,7 @@ product
193196
from Firebase) to create dynamic links.
194197
:::
195198

196-
### Adding Dynamic Link
197-
198-
Let's build an example of sharing and opening a profile page using the dynamic link. The example
199-
looks like the below:
199+
Let’s walk through an example of sharing and opening a profile page using a dynamic link. The example will look like this:
200200

201201
<figure>
202202
<img src="https://firebasestorage.googleapis.com/v0/b/ecommerceflow-docs/o/deep-link-example.gif?alt=media&token=d6f40d74-f510-4f49-8026-9ccc87896ff4"></img>
@@ -212,7 +212,7 @@ The steps to add the dynamic link are as follows:
212212
5. [Sharing dynamic link](#5-sharing-dynamic-link)
213213
6. [Testing dynamic link](#6-testing-dynamic-link)
214214

215-
#### 1. Setting up a domain
215+
### 1. Setting up a domain
216216

217217
The dynamic link requires a domain name that will be used as the URL prefix in the link.
218218

@@ -234,7 +234,7 @@ To set up the domain name, follow the steps below:
234234
<figcaption class="centered-caption">Setting up a domain for the dynamic link</figcaption>
235235
</figure>
236236

237-
#### 2. iOS setup
237+
### 2. iOS setup
238238

239239
You must complete additional configuration for the dynamic link to work on the iOS devices.
240240

@@ -278,7 +278,7 @@ To add the Associated Domain capability on App Store:
278278
<figcaption class="centered-caption">Adding Associated Domain capability to App Store</figcaption>
279279
</figure>
280280

281-
#### 3. Set URL scheme
281+
### 3. Set URL scheme
282282

283283
In this step, You will set the URL scheme. To do that:
284284

@@ -298,7 +298,7 @@ In this step, You will set the URL scheme. To do that:
298298

299299
![img_4.png](imgs/img_4.png)
300300

301-
#### 4. Setting page URL
301+
### 4. Setting page URL
302302

303303
The page URL points to the specific page in your app, which is used on the Web and for deep linking
304304
on mobile.
@@ -320,7 +320,7 @@ To set the page URL:
320320
<figcaption class="centered-caption">Setting page URL</figcaption>
321321
</figure>
322322

323-
#### 5. Sharing dynamic link
323+
### 5. Sharing dynamic link
324324

325325
You can share the dynamic link of the current page by adding the [**Generate Current Page Link
326326
**](generate-current-page-link.md)
@@ -352,7 +352,7 @@ To share the dynamic link of the page:
352352
<figcaption class="centered-caption">Sharing dynamic link</figcaption>
353353
</figure>
354354

355-
#### 6. Testing dynamic link
355+
### 6. Testing dynamic link
356356

357357
Dynamic links can not be tested in Run Mode. Instead, you will need to test the links on a real
358358
device/emulator.
@@ -400,4 +400,276 @@ To pass custom data with the link, you need to have the following:
400400
</figure>
401401

402402

403-
That's all you need to pass custom data with a **Deep Link** or **Dynamic Link**.
403+
That's all you need to pass custom data with a **Deep Link** or **Dynamic Link**.
404+
405+
## Dynamic Links with Branch.io
406+
407+
Since **Firebase Dynamic Links** have been deprecated and can no longer be used for new Firebase projects, we can integrate a powerful alternative: **[Branch.io](https://branch.io/)** — a cross-platform solution for deep linking and deferred linking.
408+
409+
With Branch, we can support robust deep linking inside FlutterFlow apps without writing a backend from scratch.
410+
411+
412+
### Branch.io Configuration
413+
414+
Start by setting up your project in the [Branch Dashboard](https://dashboard.branch.io). Once you’ve created a project:
415+
416+
**1. Note down your Branch Key**
417+
418+
Once you create a project, the first thing you’ll need to do is note down your **Branch Key**.
419+
420+
<div style={{
421+
position: 'relative',
422+
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
423+
height: 0,
424+
width: '100%'
425+
}}>
426+
<iframe
427+
src="https://demo.arcade.software/7c9mN4P0ppY3qwczmMdh?embed&show_copy_link=true"
428+
title=""
429+
style={{
430+
position: 'absolute',
431+
top: 0,
432+
left: 0,
433+
width: '100%',
434+
height: '100%',
435+
colorScheme: 'light'
436+
}}
437+
frameborder="0"
438+
loading="lazy"
439+
webkitAllowFullScreen
440+
mozAllowFullScreen
441+
allowFullScreen
442+
allow="clipboard-write">
443+
</iframe>
444+
</div>
445+
446+
<p>
447+
</p>
448+
449+
This key uniquely identifies your app and will be required later when setting up your FlutterFlow configuration.
450+
451+
**2. Set up Redirect Links**
452+
453+
In the Branch dashboard, you’ll find settings to define fallback URLs — these determine where users are sent if your app isn’t installed. Typically, you would redirect users to the App Store, Play Store, or a custom landing page.
454+
455+
<div style={{
456+
position: 'relative',
457+
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
458+
height: 0,
459+
width: '100%'
460+
}}>
461+
<iframe
462+
src="https://demo.arcade.software/EtH2CeinH2NQpianzTIC?embed&show_copy_link=true"
463+
title=""
464+
style={{
465+
position: 'absolute',
466+
top: 0,
467+
left: 0,
468+
width: '100%',
469+
height: '100%',
470+
colorScheme: 'light'
471+
}}
472+
frameborder="0"
473+
loading="lazy"
474+
webkitAllowFullScreen
475+
mozAllowFullScreen
476+
allowFullScreen
477+
allow="clipboard-write">
478+
</iframe>
479+
</div>
480+
481+
<p></p>
482+
483+
Setting up redirects is important because it ensures that your links don't break and that users always have a seamless experience, even if they need to install the app first.
484+
485+
**3. Create a Smart Link**
486+
487+
After setting up your project and redirects, you can create a new Smart Link from the **Quick Links** tab in the Branch dashboard. Here you’ll be able to set a link title, alias, add analytics tags, and customize the social media preview (such as the image, title, and description).
488+
489+
Once saved, Branch will generate a Smart Link that’s ready to use across your campaigns and app flows.
490+
491+
Here's a short demo:
492+
493+
<div style={{
494+
position: 'relative',
495+
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
496+
height: 0,
497+
width: '100%'
498+
}}>
499+
<iframe
500+
src="https://demo.arcade.software/w2egrzVVhzlcL1hTV6x7?embed&show_copy_link=true"
501+
title=""
502+
style={{
503+
position: 'absolute',
504+
top: 0,
505+
left: 0,
506+
width: '100%',
507+
height: '100%',
508+
colorScheme: 'light'
509+
}}
510+
frameborder="0"
511+
loading="lazy"
512+
webkitAllowFullScreen
513+
mozAllowFullScreen
514+
allowFullScreen
515+
allow="clipboard-write">
516+
</iframe>
517+
</div>
518+
519+
### FlutterFlow Configuration Setup
520+
521+
To make **Branch Smart Links** work in your FlutterFlow app, you’ll need to update the native configuration files via the **Custom Code** tab in your project.
522+
523+
1. Firstly, create environment variables for:
524+
- `branchHostUrl` (e.g. `brnch4.app.link`)
525+
- `branchKey` (your Branch key)
526+
527+
528+
Use `branchKey` for production and optionally `branchKeyTest` for dev environments. You can toggle modes through Branch dashboard (and also through FlutterFlow environment toggling).
529+
530+
2. Then navigate to:
531+
FlutterFlow > Custom Code > Configuration Files.
532+
533+
534+
**🔧 Android Setup**
535+
536+
1. Create two variables in `AndroidManifest.xml` file named `branchKey` and `branchHostUrl` and bind it to the environment variables we earlier created.
537+
538+
2. Add an `intent-filter` block to your **Main Activity** through the **Activity Tags hook**:
539+
540+
```xml
541+
<intent-filter android:autoVerify="true">
542+
<action android:name="android.intent.action.VIEW"/>
543+
<category android:name="android.intent.category.DEFAULT"/>
544+
<category android:name="android.intent.category.BROWSABLE"/>
545+
<data android:scheme="https" android:host="{{branchHostUrl}}"/>
546+
</intent-filter>
547+
```
548+
549+
3. Add an **App Component** block for meta-data:
550+
551+
```xml
552+
<meta-data android:name="io.branch.sdk.BranchKey" android:value="{{branchKey}}"/>
553+
<meta-data android:name="io.branch.sdk.TestMode" android:value="false"/>
554+
```
555+
556+
557+
558+
**🍎 iOS Setup**
559+
560+
1. In `Info.plist`, add a new variable called `branchKey` and bind it to the environment variable.
561+
562+
2. In `Info.plist`, add:
563+
564+
```xml
565+
<key>branch_key</key>
566+
<string>{{branchKey}}</string>
567+
```
568+
3. In `Runner.entitlements`, add a new variable called `branchHostUrl` and bind it to the environment variable.
569+
570+
4. In `Runner.entitlements`, add:
571+
572+
```xml
573+
<key>com.apple.developer.associated-domains</key>
574+
<array>
575+
<string>applinks:{{branchHostUrl}}</string>
576+
</array>
577+
```
578+
Branch automatically hosts and serves the `apple-app-site-association` file needed for Universal Links. You don’t need to manually upload it to your domain.
579+
580+
581+
**FlutterFlow Routing Setup**
582+
583+
FlutterFlow also defines a Custom URI Scheme (like `myapp://`) by default. Even if you're using Branch for web-based Smart Links, it’s a good idea to keep this in sync.
584+
585+
1. Go to:
586+
Settings & Integrations > App Settings > App Details
587+
588+
2. Scroll to **Routing & Deep Linking** section.
589+
590+
3. Under Custom URI Scheme, match the URI host/domain to what’s defined in your Branch dashboard (e.g. `brnch4://` or `dreambrush://`).
591+
592+
![custom-uri.png](imgs/custom-uri.png)
593+
594+
Even if your links mainly use `https://`, FlutterFlow's routing engine may still use the custom URI internally. Keeping this field consistent prevents confusion or route mismatches.
595+
596+
You're now ready to use Branch Smart Links in a FlutterFlow app with seamless deferred deep linking, App/Universal Link verification, and environment-based configuration.
597+
598+
### Integrate Flutter Branch SDK
599+
To integrate Branch with your FlutterFlow app, you'll use the [`flutter_branch_sdk`](https://pub.dev/packages/flutter_branch_sdk) Dart package. This will allow your app to listen to Branch links and respond accordingly.
600+
601+
602+
1. Go to your **FlutterFlow project > Pubspec Dependencies tab**, and add:
603+
604+
```js
605+
flutter_branch_sdk: ^5.0.1
606+
```
607+
(Use the latest version available from [pub.dev](https://pub.dev/packages/flutter_branch_sdk))
608+
609+
610+
2. Create a Custom Action to initialize Branch SDK. This ensures the Branch session is set up when your app starts.
611+
612+
```js
613+
import 'package:flutter_branch_sdk/flutter_branch_sdk.dart';
614+
615+
Future initBranch() async {
616+
// Add your function code here!
617+
await FlutterBranchSdk.init();
618+
}
619+
620+
```
621+
622+
Call this action inside the **Final Actions** of your `main.dart`.
623+
624+
3. Create another custom action to listen for Branch link clicks and optionally route the user:
625+
626+
```js
627+
628+
// Automatic FlutterFlow imports
629+
import '/flutter_flow/flutter_flow_theme.dart';
630+
import '/flutter_flow/flutter_flow_util.dart';
631+
import '/custom_code/actions/index.dart'; // Imports other custom actions
632+
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
633+
import 'package:flutter/material.dart';
634+
// Begin custom action code
635+
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
636+
637+
import 'dart:async';
638+
import 'package:flutter_branch_sdk/flutter_branch_sdk.dart';
639+
import 'package:flutter/services.dart';
640+
641+
StreamSubscription<Map>? _branchSubscription; // stream subscription that listens for branch links
642+
final Set<String> _handledBranchLinks = {};
643+
644+
Future handleBranchDeeplink(Future Function(dynamic data) onLinkOpened) async {
645+
// Add your function code here!
646+
647+
if (_branchSubscription != null) return; // If already listening, ignore link
648+
649+
_branchSubscription = FlutterBranchSdk.listSession().listen(
650+
(data) async {
651+
final clicked = data['+clicked_branch_link'] == true;
652+
if (!clicked) return;
653+
654+
final uniqueId = data['~referring_link'] ?? data['deeplink_path'] ?? '';
655+
656+
if (_handledBranchLinks.contains(uniqueId)) return;
657+
_handledBranchLinks.add(uniqueId);
658+
659+
await onLinkOpened(Map<String, dynamic>.from(data)); // call action defined by user & pass the link data.
660+
},
661+
onError: (error) {
662+
if (error is PlatformException) {
663+
print('[Branch] PlatformException: ${error.code} - ${error.message}');
664+
} else {
665+
print('[Branch] Unknown error: $error');
666+
}
667+
},
668+
);
669+
}
670+
671+
```
672+
673+
You can pass custom key-value pairs like `"page": "paywall"` or `"navigation_type": "bottom_sheet"` when creating the Branch link, and retrieve them here to decide which screen to navigate to in FlutterFlow.
674+
675+
Be sure to test both fresh installs (deferred deep links) and existing app sessions to confirm that your actions run as expected.
203 KB
Loading

0 commit comments

Comments
 (0)