Flutter Deep Linking: A Warm Welcome to Seamless Navigation

CodeStax.Ai
7 min readOct 30, 2024

--

Flutter Deep Linking

The promotional links on Flutter apps take you to the correct screens when a user click on them — have you ever wondered why? For a smooth user experience, this magic is crucial. In this digital age, ensuring a good UX is of great importance and this becomes apparent when users consume applications through websites, email, and mobile apps.

This smooth hand-off between web and mobile URLs is not just luck — it is made possible through technology called deep-linking. Deep linking ensures that users can be directly redirected to to a specific screen like product page or any specific pages directly.

What is Deep Linking?

Deep linking is the action of delivering users to specific in-app content — from wherever they are online. One of the example of deep linking is when the call to action in an abandoned cart email leads users back to checkout or even a specific feature within the app.

There are mainly 3 types of deep linking:

  • Basic Deep Linking: Link that user directly to the content within the app if app is intalled.
  • Deferred Deep Linking: Even if the app is not installed, user will go to a specific content when they will install the app.
  • Universal Links (iOS) and App Links (Android): Advance form of deep linking that will handle both installed and non-installed scenarios and work across browsers.

Why Do We Need Deep Linking?

Before getting know why deep linking is needed? Think about a scenario, clicking on a link in a promotional email will open the home page rather than related product page within the app. For applications that are rich and content-heavy, like e-commerce websites and social media platforms, this is of significant concern. If the user is expected to manually navigate to the desired page when clicking a link, it creates friction and the user loses interest.

What Happens If We Have No Deep Linking Feature?

If your app lacks deep linking, users:

  • Lose context: Upon opening a link to your app and find themselves on the default homepage, instead of the expected content they were seeking, the user loses context and becomes disoriented.
  • Experience higher drop-offs: Users often tend to leave the app when encountering issues during promotions; they are likely to exit if they struggle to locate the relevant page promptly.
  • Struggle with delivering an user experience can result in decreased user interaction and loyalty issues. Apparent, in applications that heavily depend on complex content browsing systems.

How Does it work?

So, how does it work this is the question right ?So By using a deep linking engine, you can create two journeys: one for users with the app and one for users without the app.

For users with the app process is straightforward — when they will click on the link, they are instantly redirected to the specific content. (e.g. Specific part of the features).

But for users who don’t have apps for them path is little bit longer but still smooth. This is where deferred deep linking comes into play. When a non app users click on the same link they are first redirected on app stores to download the apps and after installation when they will open the app, instead of landing to home page they are redirected to the intended content.

Real-Life Examples of Deep Linking

  1. Instagram: When you click on the Instagram profile link, in a browser it will take you directly to the Instagram app of that particular profile page.
  2. Amazon: When you click on a link, in a email promotions on Amazon website it will take you on exactly correct product page within the app interface regardless of whether app is opened on not.
  3. YouTube: YouTube utilizes linking to guide users to videos through shared links.

Now we have covered what deep linking and how it works so let’s go for setup deep linking in your app and demo.

Step 1: Create a New Flutter Project (or Use Existing One)

flutter create deep_link_demo
cd deep_link_demo

Command to open an existing project:

cd path/to/your/project

Step 2: Add the uni_links Package to Your Project

So now in step 2 we need to add the uni_links package in our pubspec file, that will help us in handling the deep linking in Flutter. So for setup follow these steps-

  1. Open the pubspec.yaml file in your project.
  2. Add the following dependency under dependencies.
dependencies:
flutter:
sdk: flutter
uni_links: ^0.5.1

3. Run the following command to install the package:

flutter pub get

Step 3: Configure Android for Deep Linking

Now the step 3 is to configure the Deep Linking in the android manifest file so for that follow these steps-

  1. Open the android/app/src/main/AndroidManifest.xml file in your project.
  2. Inside the <activity> tag of AndroidManifest.xmlfile in your project add the following intent filter tag to handle the deep links:
<intent-filter>
<!-- Handles view actions, like opening URLs -->
<action android:name="android.intent.action.VIEW"/>

<!-- Default category for most implicit intents -->
<category android:name="android.intent.category.DEFAULT"/>

<!-- Allows the app to be opened from a browser -->
<category android:name="android.intent.category.BROWSABLE"/>

<!-- Specifies the URL structure the app responds to (scheme: myapp, host: content) -->
<data android:scheme="myapp" android:host="content"/>
</intent-filter>
  • Please replace myapp with the custom scheme you want to use(e.g., myapp is fine for local testing).
  • content is the host you define. It is upto you. You can change it with whatever actual deep link URL you are using.

3. Please make sure this intent filter is placed inside the main <activity> tag in your AndroidManifest.xml.

Step 4: Handle the Deep Link in Flutter

Now we’ve set up deep linking for Android, let’s handle the deep links in Flutter so follow these steps:

  1. Open the lib/main.dart file.
  2. Modify the main.dart to import uni_links and listen for deep links.

Here’s how you can update your main.dart:

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:uni_links/uni_links.dart';
import 'package:flutter/services.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
String _currentPage = "Home"; // Default page name
String _deepLink = "No deep link detected";

@override
void initState() {
super.initState();
_initDeepLinkListener();
}

// Initialize the deep link listener
Future<void> _initDeepLinkListener() async {
try {
// Get initial deep link if the app is launched with one
final initialLink = await getInitialLink();
if (initialLink != null) {
_handleDeepLink(initialLink);
}

// Listen to incoming deep links after the app is already running
uriLinkStream.listen((Uri? link) {
if (link != null) {
_handleDeepLink(link.toString());
}
});
} on PlatformException {
print("Failed to get deep link");
}
}

// Function to handle the deep link and update the page
void _handleDeepLink(String link) {
setState(() {
_deepLink = link;
if (link.contains("profile")) {
_currentPage = "Profile";
} else if (link.contains("dashboard")) {
_currentPage = "Dashboard";
} else {
_currentPage = "Home";
}
});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(
title: Text('$_currentPage Page'), // Dynamic page title
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Welcome to the $_currentPage Page!',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
Text(
'Deep Link: $_deepLink',
style: TextStyle(fontSize: 16, color: Colors.grey),
),
],
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _getCurrentIndex(), // Update based on the current page
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
BottomNavigationBarItem(
icon: Icon(Icons.dashboard),
label: 'Dashboard',
),
],
onTap: (index) {
_onBottomNavTapped(index);
},
),
),
);
}

// Update the selected index based on the current page
int _getCurrentIndex() {
if (_currentPage == "Profile") {
return 1;
} else if (_currentPage == "Dashboard") {
return 2;
} else {
return 0;
}
}

// Handle bottom navigation taps
void _onBottomNavTapped(int index) {
setState(() {
if (index == 0) {
_currentPage = "Home";
} else if (index == 1) {
_currentPage = "Profile";
} else if (index == 2) {
_currentPage = "Dashboard";
}
});
}
}

Let’s see the code and and its short explanation:

So there are three main components in the code:

  • Deep Link Listener: To monitor incoming deep links, we have used the uni_links package.
  • Dynamic Page Navigation: Using the deep link, we navigate to various pages such as Home, Profile, and Dashboard.
  • Bottom Navigation Bar: To manually move between various sites, a bottom navigation bar is used, which replicate deep linking operations through user interface interaction.

Now that our software is fully functional, users can:

  • access deep links and navigate directly to the relevant screen.
  • Manually navigate between pages using the bottom navigation bar.

Step 5: Testing Deep Links on Web (for Flutter Web Projects)

  1. Run the app locally:
flutter run -d chrome

2. Modify the URL to Simulate a Deep Link:

To replicate the desired effect, run the following deep links-

For example, let’s suppose the app is running atlocalhost:8080 so below, these are the urls that are deep linked:

Now if you want to test the app then by hitting the following urls you can get the different-2 screens that are deep-linked.

CONCLUSION:

Deep linking is the action of delivering users to specific in-app content — from wherever they are online. Alongwith we have explored about deep linking in flutter for seamless navigation for users. It’s setup and configuration. We got to know that what is different kind of deep linking and why it is important alongwith its demo.

About the Author:

Sidhant Singh is currently serving as a Software Development Engineer at CodeStax.Ai, where he is gaining hands-on experience in software development. With a focus on both front-end and back-end technologies, Sidhant is passionate about tackling challenges and exploring new concepts in the field.

About CodeStax.Ai

At CodeStax.Ai, we stand at the nexus of innovation and enterprise solutions, offering technology partnerships that empower businesses to drive efficiency, innovation, and growth, harnessing the transformative power of no-code platforms and advanced AI integrations.

But the real magic? It’s our tech tribe behind the scenes. If you’ve got a knack for innovation and a passion for redefining the norm, we’ve got the perfect tech playground for you. CodeStax.Ai offers more than a job — it’s a journey into the very heart of what’s next. Join us, and be part of the revolution that’s redefining the enterprise tech landscape.

--

--

CodeStax.Ai
CodeStax.Ai

Written by CodeStax.Ai

Tech tales from our powerhouse Software Engineering team!

No responses yet