Effortless Routing & Deeplink in Flutter Using go_router

Learn how to easily implement routing and deep link handling in your Flutter app with go_router

Dwi Randy Herdinanto
5 min readFeb 12, 2023

Outline

  • Deeplink Introduction
  • Setup Flutter Project
  • iOS & Android Configuration
  • Test Deeplink
  • Conclusion

Deeplink Introduction

Deep linking allows you to access a specific part of an app using a web browser link. This link can be used to direct users to specific content within the app, such as events, news updates, and more, and can also pass along custom data, like promotional codes. This is useful when you want to share specific content with someone, rather than just sending them to the app’s homepage to search for it themselves.

For example, if you wanted to share this article with a friend, you would send them a link directly to this article, instead of just sending them to the website and expecting them to search for it. In order to handle these deep links, you will need to set up the appropriate navigation within your app.

Additionally, when a deep link is triggered, your app may already be running in the background. In this case, you will need to handle the deep link click even when your app is not in the foreground.

Setup Flutter Project

First we will create an simple project that has 2 pages which are home pages and news page, then we will try to open home or profile page by using the deeplink URL and also parse the parameters from .

Step 1. Create Flutter Project

Create an empty flutter project using this command flutter create medium_deeplink

Step 2. Add go_router Dependency

go_router is a routing library for Flutter, which provides a simple and efficient way to navigate between pages in a Flutter app. It provides a declarative way of defining routes, which makes it easier to understand and maintain your app’s navigation structure.

Before we use go_router we need to add the package into our application, we can use this command to add go_router into our flutter application

flutter pub add go_router

Step 2. Create Home Page

We will have a home page with a button that, when pressed, should navigate to a news page with a userid of dwirandyh and a path of flutter-deeplink-example.

// lib/home_page.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);

@override
State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
title: const Text("Profile Page"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: ElevatedButton(
onPressed: () {
context.pushNamed("news", params: {
"id": "dwirandyh",
"path": "flutter-deeplink-example"
});
},
child: const Text("Go to Profile Page"),
),
)
],
),
);
}
}

Step 3. Create News Page

In the next step, we will create the news page, which is a simple but crucial component of our app. This page will receive parameters from the home page and use them to display the news URL.

// lib/news_page.dart

import 'package:flutter/material.dart';

class NewsPage extends StatelessWidget {
final String userId;
final String path;

const NewsPage({Key? key, required this.userId, required this.path})
: super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
title: const Text("News Detail Page"),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 24),
const Center(
child: Text(
"News Detail Information",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
)),
SizedBox(height: 16),
Text("User ID: $userId"),
Text("News URL: \nhttps://$userId.medium.com/$path")
],
),
);
}
}

Step 4. Define The Router Configuration

We have create a page that we want to navigate in our application, to make it possible to navigate between these page we need to create a router configuration.

// lib/router.dart

import 'package:go_router/go_router.dart';
import 'package:medium_deeplink/home_page.dart';
import 'package:medium_deeplink/news_page.dart';

final GoRouter router = GoRouter(routes: [
GoRoute(
path: "/",
builder: (context, state) => const HomePage(),
),
GoRoute(
path: "/news/:id/:path",
name: "news",
builder: (context, state) => NewsPage(
userId: state.params["id"].toString(),
path: state.params["path"].toString(),
),
)
]);

In this case, we’ve defined two routes. Each route path will be matched against the location to which the user is navigating. Only a single route can be matched, specifically the one whose path matches the entire location.

Step 5. Apply Router Configuration Into Application

After we have created the router configuration, we need to implement the router by replacing MaterialApp() into MaterialApp.router()

// lib/main.dart

import 'package:flutter/material.dart';
import 'package:medium_deeplink/router.dart';

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

class MyApp extends StatelessWidget {
const MyApp({super.key});

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Flutter Deeplink Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routerConfig: router,
);
}
}

iOS & Android Configuration

To enable deeplink in our application, we have to add some configuration in our native project configuration

Step 1. Enable Deeplink in Android

To enable deeplink in Android we have to add a metadata tag and intent filter to AndroidManifest.xml inside the <activity> tag with the ".MainActivity"

<!-- Deep linking -->
<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="dwirandyh.medium.com" />
<data android:scheme="https" />
</intent-filter>

In the data configuration we can change android:host with the url of the website that we have. So that we we open that URL it will open our application instead of open browser

Step 2. Enable Deeplink in iOS

To enable deeplink in iOS application we have to add some configuration inside our info.plist file

<key>FlutterDeepLinkingEnabled</key>
<true/>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>dwirandyh.medium.com</string>
<key>CFBundleURLSchemes</key>
<array>
<string>appscheme</string>
</array>
</dict>
</array>

We can change the CFBundleURLName into our website URL, and for CFBundleURLSchemes we can change it into scheme that we want, then when a user opens a URL with a matching scheme, the system will launch the app associated with that scheme.

Test Deeplink

With the deeplink configuration in place, our app is now equipped to handle deep links and open specific pages in response to the deeplink being opened on our device.

To verify that everything is working correctly, we can test our setup by using the simulator. This allows us to simulate the behavior of deep links and ensure that our app is responding as expected.

Test on Android emulator

To test with an Android emulator, give the adb command an intent where the host name matches the name defined in AndroidManifest.xml:

adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d "http://dwirandyh.medium.com/news/dwirandyh/deeplink" \
com.example.medium_deeplink

Test on iOS Simulator

Use the xcrun command to test on the iOS Simulator:

xcrun simctl openurl booted "appscheme://dwirandyh.medium.com/news/dwirandyh/deeplink

Conclusion

In conclusion, routing and deep linking in Flutter can be easily implemented using the go_router library. By following the steps outlined in this article, you can set up your Flutter project, configure both iOS and Android for deep linking, and test your deep link.

By utilizing the go_router library, you can declare your routes in a simple and efficient manner, making it easier to understand and maintain your app’s navigation structure.

This article provides a step-by-step guide to implementing deep links in your Flutter app and can serve as a helpful resource for developers who want to take advantage of the benefits of deep linking in their Flutter applications.

You can see full source code in my repository below

--

--

Dwi Randy Herdinanto

A software developer that enthusiastic about mobile applications