-
Notifications
You must be signed in to change notification settings - Fork 110
Add branch library documentation #340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ keywords: [FlutterFlow, Deep Linking, Dynamic Linking, Concepts] | |
# Deep & Dynamic Linking | ||
|
||
:::danger[Support for Dynamic Links] | ||
On August 25th, 2025, Firebase Dynamic Links will be shut down. Read more about the [**announcement here**](https://firebase.google.com/support/dynamic-links-faq). It's recommended to start exploring alternative solutions like [**Branch.io**](#dynamic-links-with-branchio) for link management and deep linking. | ||
On August 25th, 2025, Firebase Dynamic Links will be shut down. Read more about the [**announcement here**](https://firebase.google.com/support/dynamic-links-faq). It's recommended to start exploring alternative solutions like [**Branch.io**](#deep-links-with-branchio) for link management and deep linking. | ||
::: | ||
|
||
Adding deep and dynamic linking allows you to share a special type of link that takes the user right | ||
|
@@ -402,7 +402,7 @@ To pass custom data with the link, you need to have the following: | |
|
||
That's all you need to pass custom data with a **Deep Link** or **Dynamic Link**. | ||
|
||
## Dynamic Links with Branch.io | ||
## Deep Links with Branch.io | ||
|
||
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. | ||
|
||
|
@@ -674,3 +674,291 @@ Be sure to test both fresh installs (deferred deep links) and existing app sessi | |
For a complete walkthrough, check out the tutorial video: | ||
<div class="video-container"><iframe src="https://www.youtube.com/embed/nEBot6-zhfY?si=y-flWx8zoGH8mgjM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div> | ||
::: | ||
|
||
|
||
## Branch Deeplinking Library | ||
|
||
If you don't want to implement the Branch Library from scratch, we have introduced the Branch Deep Linking Library that you can import from the Marketplace completely free. | ||
|
||
This library sets up everything you need for routing users into your app using Branch’s smart links — with native configuration, link handling, and deep link helpers already wired in. | ||
|
||
### Install Library | ||
|
||
To install the Branch Deep Linking Library, open the FlutterFlow Marketplace, search for the library, and click **+ Add for Free**. | ||
|
||
:::tip[marketplace] | ||
You can find the [**Library here**](https://marketplace.flutterflow.io/item/oAco1HzQHxtOVE1ssTcC). | ||
::: | ||
|
||
This installs the library into your FlutterFlow account, and you can reuse it across any number of projects. | ||
|
||
 | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
To add it to a specific project, go to **Settings > Project Dependencies**, click Add Library, and search for Branch. | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Branch Setup | ||
|
||
You’ll need two values from your Branch dashboard: | ||
|
||
- **Branch Live Key** – your production API key from the Branch dashboard | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- **Custom Domain** – your configured link domain (e.g., yourapp.app.link) | ||
This is the domain used to generate and handle smart links for your app. | ||
|
||
We recommend storing these values in Environment Variables so you can: | ||
- Manage them per environment (e.g. dev vs prod Branch keys) | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Easily assign them to the library’s configuration when adding it to a project. | ||
|
||
**Adding Library Values** | ||
|
||
When you add the Branch Deep Linking Library to your project, it will prompt you to provide three values: | ||
|
||
- `branchApiKey` | ||
- `branchHostUrl` | ||
- `isTestMode` | ||
|
||
Use the environment variables you created to populate these values. | ||
|
||
:::info | ||
`isTestMode` should be set to false when running your app in production. | ||
::: | ||
|
||
Here’s a quick demo to show how to configure those values inside your library panel. | ||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%' | ||
}}> | ||
<iframe | ||
src="https://demo.arcade.software/AWUZbgiNKpKgwKjxAM17?embed&show_copy_link=true" | ||
title="" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
|
||
<p></p> | ||
|
||
**Initialize the Branch SDK** | ||
|
||
Open your `main.dart` file in FlutterFlow and add the `initBranch` custom action under the **Final Actions** section. This ensures the **Branch SDK** is initialized when your app launches. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If possible, a screenshot after this line would be helpful! |
||
|
||
|
||
### Handle Branch Deeplink [Custom Action] | ||
|
||
To receive and act on deep link data, go to your **Entry Page** or **Logged-In Page** and add the `handleBranchDeeplink` action as the first action in the page flow. | ||
|
||
This `handleBranchDeeplink` action listens for incoming Branch Deeplinks and handles routing logic. This action should be added to your Entry Page or Logged-In Page under the **onPageLoad** trigger. It initializes a stream listener that waits | ||
for Branch links to be opened (either deferred or direct). | ||
|
||
When a link is received, the `onLinkOpened` callback is triggered with | ||
the link data, allowing you to perform custom navigation or logic. You can perform your navigation logic in this action callback. | ||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%' | ||
}}> | ||
<iframe | ||
src="https://demo.arcade.software/aRZju3GUJAzaqAUZs87G?embed&show_copy_link=true" | ||
title="" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
|
||
<p></p> | ||
|
||
**`linkData` Action Parameter** | ||
|
||
The `handleBranchDeeplink` action receives a `linkData` object that contains all the metadata sent with the link. The `linkData` parameter is a Map containing useful information from the Branch link: | ||
|
||
- **`$canonical_identifier`:** The original route path used when the link was generated (e.g. `/imageDetails/:id`). | ||
|
||
- **`~referring_link`:** The full Branch URL that was clicked. | ||
|
||
- **`page`:** The target page or screen the link is meant to open (e.g. paywall). This is a custom parameter set by the user when generating the link. | ||
|
||
- Any custom parameters added during link creation (e.g. `campaign`, `productId`, `referrer`, etc.) | ||
|
||
This lets you write flexible, conditional navigation logic based on what was shared. | ||
|
||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%' | ||
}}> | ||
<iframe | ||
src="https://demo.arcade.software/FRDKejqwWVAmS27RJeQH?embed&show_copy_link=true" | ||
title="" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
|
||
<p></p> | ||
|
||
|
||
|
||
|
||
Use the link data from this callback to: | ||
- Navigate to a page. | ||
- Show a bottom sheet. | ||
- Load content from Firestore using a referenced ID. | ||
|
||
|
||
|
||
|
||
|
||
|
||
### Generate Link [Custom Action] | ||
|
||
|
||
The `generateLink` action allows you to create a custom Branch Smart Link directly from your FlutterFlow app. | ||
|
||
This is especially useful when you want to let users: | ||
- Share app content (like a post, product, or image). | ||
- Invite others with referral codes. | ||
- Trigger deep links that take recipients to specific app screens. | ||
|
||
The action accepts the following parameters: | ||
|
||
- **`canonicalIdentifier`** – A unique path for the content (e.g. `/imageDetails/:id`). This becomes the key reference used when routing the user back into the app. | ||
|
||
- **`title`** – The link's title (used in social previews or analytics) | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- **`description`** – (Optional) A short description of the content | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- **`metadata`** – A dynamic map of custom parameters to include with the link | ||
(e.g. page: "imageDetails", imageRef: "abc123", etc.) | ||
|
||
- **`linkProperties`** – A dynamic map for configuring how the link behaves | ||
(e.g. set the `feature`, `channel`, `campaign`, or `stage` for analytics). | ||
|
||
### Branch Helper Functions | ||
|
||
These functions help you safely work with deep link data, extract values, and conditionally navigate based on link metadata. | ||
|
||
- **`isTargetingPage(linkData, targetPage)`** - Checks whether the page value in the link data matches a specific screen name. The `page` parameter is set by the user when generating the link from Branch dashboard or FlutterFlow. | ||
|
||
- **`getCanonicalIdentifierFromLink(linkData)`** - Returns the canonical path (e.g. `/imageDetails/abc123`) that was originally attached to the smart link. Useful for extracting the base route or content reference associated with the shared link. | ||
|
||
- **`getReferringLinkFromLink(linkData)`** - Retrieves the full Branch smart link URL from the data (typically under the `~referring_link` key). Useful for tracking, analytics, or verifying the source of the link. | ||
|
||
- **`getLastPathSegmentFromMap(linkData, key)`** - Extracts the last path segment (e.g `abc123`) from a URI stored inside a link data field (e.g. `/imageDetails/abc123`). Useful for extracting the ID from a link. | ||
|
||
- **`getLinkValue(linkData, key)`** : Safely retrieves any single value from the link data Map. Returns null if not found. (e.g retrieving `showPromo` attribute value from the `linkData`) | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- **`createLinkProperties(...)`** : Returns a Branch Link Properties map used when generating a smart link. You can define values like: feature, campaign, stage, channel, alias or tags or custom fallback URLs. Useful for organizing and tracking generated links for marketing or referrals. | ||
PoojaB26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
|
||
### DreamBrush Link Generation Example | ||
|
||
In the DreamBrush app, we can use `generateLink` after a user finishes generating an image. | ||
The link could include: | ||
- **page**: Current Page Route that is `/imageDetails/:imageRef`. | ||
- **title**: "Check out my AI image!" | ||
|
||
This link can then be shared via WhatsApp, email, or social media — and when clicked, it brings the recipient directly to that content inside the app. | ||
|
||
Here's a quick example of generating a Branch link from a page that uses a Firebase Document ID as a route parameter. | ||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%' | ||
}}> | ||
<iframe | ||
src="https://demo.arcade.software/SELEpnhCryYrZD7KokAl?embed&show_copy_link=true" | ||
title="" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
|
||
<p> | ||
</p> | ||
|
||
Now in your `handleBranchDeeplink` action callback, add the additional logic to handle such custom links: | ||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%' | ||
}}> | ||
<iframe | ||
src="https://demo.arcade.software/kZ7uvnohpGIER3ZTxPR8?embed&show_copy_link=true" | ||
title="" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
|
||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.