Implementing Authentication and Navigation in Flutter Web using go_router

In today’s digital world, where flutter web navigation and flutter web routing are essential, implementing robust authentication and seamless navigation are crucial aspects of any web application.
When it comes to Flutter Web, developers face unique challenges in setting up authentication and navigation due to the nature of web-based interactions.
Fortunately, there is a powerful package called go_router that simplifies the process and enhances the user experience.
In this article, we will delve into the importance of authentication and navigation in Flutter Web, with a specific focus on flutter web navigation and routing. We will also explore how go_router can be utilized to overcome these challenges effectively.
Authentication forms the backbone of secure web applications, ensuring that only authorized users can access sensitive information or perform specific actions. Implementing authentication in Flutter Web is of utmost importance as it provides several benefits and plays a crucial role in the overall security and integrity of your application.
By recognizing the benefits and understanding the importance of implementing authentication in Flutter Web, you can ensure the security, privacy, and integrity of your application.
It enables you to provide a seamless and trusted user experience while protecting sensitive data from unauthorized access.
Invest the necessary time and effort into implementing robust authentication mechanisms to establish a strong foundation for your Flutter Web application's security and success.
Seamless navigation is vital for creating intuitive and user-friendly web applications. In Flutter Web, navigation plays a crucial role in providing a smooth user experience and ensuring users can effortlessly move between different sections of your application. Let's explore the benefits and importance of implementing effective navigation in your Flutter Web projects.
Incorporating effective navigation in your Flutter Web application not only enhances the user experience but also helps achieve business goals, improve conversion rates, and increase user retention. By adopting a user-centric approach and designing a clear and intuitive navigation system, you can provide a seamless browsing experience that keeps users engaged, satisfied, and coming back for more.
Investing time and effort in understanding your users' needs, organizing your content, and implementing well-designed navigation elements will undoubtedly contribute to the success and usability of your Flutter Web application.
Learn How to Build a Complex Navigation Stack with Flutter
Go Router is a powerful Flutter package specifically designed for managing navigation in Flutter Web applications. It offers several benefits over the standard Flutter navigation system, making it an excellent choice for implementing navigation in Flutter Web projects. Developers can take complete advantage of Go Router to create a more insightful navigation experience that is in perfect sync with web standards and thus provides users with a seamless interaction flow.
While Flutter Navigation 2.0 provides a solid foundation for navigation, go_router offers additional features and flexibility specifically tailored for Flutter Web. It simplifies the navigation process and improves overall performance, resulting in a smoother user experience. Go Router leverages the browser history API to manage the page stack and back navigation, allowing users to navigate backward through the application history using the browser’s back button or other navigation gestures. This feature ensures consistent behavior and enhances user convenience.
Furthermore, Go Router's architecture supports the concept of declarative routing. Under this framework, developers can describe routes and their complementary widgets in a more organized and sorted way. This leads to improved code readability as well as facilitates convenient maintenance as the growth of the application continues.
To utilize Go Router efficiently, it is important to develop an understanding of navigation concepts in Flutter Web. There are two primary approaches to navigation that exist: imperative and declarative.
The implementation of common routing patterns is extremely critical for creating intuitive navigation flows in your Flutter web applications. Go Router supports various routing techniques:
1final router = GoRouter(
2 routes: <GoRoute>[
3 GoRoute(
4 path: '/',
5 redirect: (_, __) => '/dashboard',
6 ),
7 GoRoute(
8 path: '/login',
9 pageBuilder: (context, state) {
10 return MaterialPage(child: const LoginPage());
11 },
12 ),
13 GoRoute(
14 path: '/:kind(dashboard|settings)',
15 pageBuilder: (context, state) => MaterialPage(
16 child: HomePage(kind: state.pathParameters['kind']!),
17 ),
18 routes: [
19 GoRoute(
20 path: DetailsPage.route,
21 pageBuilder: (context, state) {
22 final id = state.pathParameters['id'];
23 return MaterialPage(
24 child: PlantDetailsPage(id: id),
25 );
26 },
27 ),
28 ],
29 ),
30 ],
31);
32
By becoming proficient in these routing patterns, you amplify not only the user experience but also the SEO potential of your application.
The most crucial factor to consider for any web application is Performance, and Go Router is designed with this as the fundamental foundation. To ensure optimal performance, consider the following strategies:
Along with everything else that impacts performance, efficient error handling is mandatory for a sturdy routing solution. Go Router offers strategies to manage errors effectively:
1final router = GoRouter(
2 errorBuilder: (context, state) {
3 return Center(
4 child: Text(state.error?.message ?? 'Unknown error'),
5 );
6 },
7 errorPageBuilder: (context, state) {
8 return MaterialPage(
9 child: Scaffold(
10 body: Center(
11 child: Text(state.error?.message ?? 'Unknown error'),
12 ),
13 ),
14 );
15 },
16);
17
Also read: Creating Augmented Reality App with Flutter
flutter create my_app
1dependencies:
2 go_router: ^7.0.1
3 hive: ^2.2.3
4 hive_flutter: ^1.1.0
5 dev_dependencies:
6 build_runner: ^2.4.2
7 hive_generator: ^2.0.0
Here, the hive is used to store local data. You can use shared_preferences or any other local data storage package instead of the hive.
Create a common service to handle authentication-related logic, such as user authentication, session management, and secure storage.
This service will serve as the foundation for implementing authentication in your Flutter Web application.
1flutter pub run build_runner build --delete-conflicting-outputs
This command will generate user_data.g.dart at the same location as user_data.dart
Initialize go_router in your application and define the initial route.
You can set up a default route and handle the navigation based on the user's authentication status.
1import 'package:flutter/material.dart';
2import 'package:go_router/go_router.dart';
3
4import '../pages/home_page.dart';
5import '../pages/login_page.dart';
6import '../services/app_service.dart';
7
8part 'redirection.dart';
9
10final router = GoRouter(
11 redirect: _redirect,
12 debugLogDiagnostics: true,
13 refreshListenable: AppService.instance,
14 navigatorKey: AppService.instance.navigatorKey,
15 routes: <GoRoute>[
16 GoRoute(
17 path: '/',
18 redirect: (_, __) => HomePage.route,
19 ),
20 GoRoute(
21 path: LoginPage.route,
22 pageBuilder: (context, state) => const MaterialPage(child: LoginPage()),
23 ),
24 GoRoute(
25 path: HomePage.route,
26 pageBuilder: (context, state) => const MaterialPage(child: HomePage()),
27 ),
28 ],
29);
Redirect users based on their authentication status. If a user is not authenticated, redirect them to the login page. Otherwise, navigate them to the home page or any other authorized sections.
1part of 'router.dart';
2
3String? _redirect(BuildContext context, GoRouterState state) {
4 final isLoggedIn = AppService.instance.isLoggedIn;
5 final isLoginRoute = state.matchedLocation == LoginPage.route;
6
7 if (!isLoggedIn && !isLoginRoute) {
8 return LoginPage.route;
9 } else if (isLoggedIn && isLoginRoute) {
10 return HomePage.route;
11 }
12 return null;
13}
Define routes for different screens and components of your application.
With go_router, you can easily map routes to specific pages or widgets.
1import 'package:flutter/material.dart';
2import 'package:flutter_web_plugins/url_strategy.dart';
3import 'package:hive_flutter/hive_flutter.dart';
4
5import 'models/user_data.dart';
6import 'routing/router.dart';
7import 'services/app_service.dart';
8
9void main() async {
10 WidgetsFlutterBinding.ensureInitialized();
11 await Hive.initFlutter();
12 Hive.registerAdapter(UserDataAdapter());
13 await Hive.openBox('App Service Box');
14 runApp(const MyApp());
15}
16
17class MyApp extends StatefulWidget {
18 const MyApp({super.key});
19
20 @override
21 State<MyApp> createState() => _MyAppState();
22}
23
24class _MyAppState extends State<MyApp> {
25 @override
26 void initState() {
27 super.initState();
28 usePathUrlStrategy();
29 AppService.instance.initialize();
30 }
31
32 @override
33 Widget build(BuildContext context) {
34 return MaterialApp.router(
35 title: 'Web Authentication',
36 debugShowCheckedModeBanner: false,
37 routerDelegate: router.routerDelegate,
38 routeInformationParser: router.routeInformationParser,
39 routeInformationProvider: router.routeInformationProvider,
40 );
41 }
42}
Create the necessary pages and widgets for your application.
Each page should correspond to a specific route defined in the go_router configuration and provide the desired functionality.
Design your pages with user-friendly interfaces, intuitive navigation elements, and responsive layouts to ensure a pleasant user experience across various devices.
1import 'package:flutter/material.dart';
2import 'package:go_router/go_router.dart';
3import 'package:web_auth_demo/models/user_data.dart';
4import 'package:web_auth_demo/services/app_service.dart';
5
6import 'home_page.dart';
7
8class LoginPage extends StatefulWidget {
9 static const route = '/login';
10
11 const LoginPage({Key? key}) : super(key: key);
12
13 @override
14 State<LoginPage> createState() => _LoginPageState();
15}
16
17class _LoginPageState extends State<LoginPage> {
18 final _emailCtrl = TextEditingController();
19 final _passwordCtrl = TextEditingController();
20
21 @override
22 Widget build(BuildContext context) {
23 return Scaffold(
24 body: ListView(
25 padding: const EdgeInsets.all(16),
26 children: [
27 const Text(
28 'Login to your account',
29 style: TextStyle(
30 fontSize: 16,
31 fontWeight: FontWeight.w600,
32 ),
33 ),
34 const SizedBox(height: 32),
35 TextFormField(
36 controller: _emailCtrl,
37 ),
38 const SizedBox(height: 16),
39 TextFormField(
40 controller: _passwordCtrl,
41 obscureText: true,
42 ),
43 const SizedBox(height: 20),
44 ElevatedButton(
45 onPressed: () {
46 AppService.instance.setUserData(UserData(
47 id: DateTime.now().millisecondsSinceEpoch.toString(),
48 email: _emailCtrl.text,
49 ));
50 context.go(HomePage.route);
51 },
52 child: const Text('Login'),
53 )
54 ],
55 ),
56 );
57 }
58}
1import 'package:flutter/material.dart';
2import 'package:go_router/go_router.dart';
3
4import '../pages/login_page.dart';
5import '../services/app_service.dart';
6
7class HomePage extends StatefulWidget {
8 static const route = '/home';
9
10 const HomePage({Key? key}) : super(key: key);
11
12 @override
13 State<HomePage> createState() => _HomePageState();
14}
15
16class _HomePageState extends State<HomePage> {
17 @override
18 Widget build(BuildContext context) {
19 return Scaffold(
20 appBar: AppBar(
21 title: const Text('Home page'),
22 actions: [
23 IconButton(
24 onPressed: () async {
25 await AppService.instance.terminate();
26 if (mounted) context.go(LoginPage.route);
27 },
28 icon: const Icon(Icons.logout),
29 )
30 ],
31 ),
32 body: Center(
33 child: Text('Login to ${AppService.instance.currentUser!.email}'),
34 ),
35 );
36 }
37}
Explore a comparison between the performance of an app built with Native Android and Flutter.
While Go Router is a powerful and reliable option for Flutter Web navigation, it’s important to compare it with other routing solutions to determine the best option for your project.
While making a choice for a routing solution, consider your project’s specific needs, the complexity of your navigation, and your team's familiarity and comfort with the tools. After following a thorough approach of evaluation of all these factors, you can select the most efficient and fitting routing solution for your Flutter Web application.
Implementing authentication and navigation in Flutter Web is vital for creating secure and user-friendly web applications.
The go_router package offers a powerful solution for managing navigation, providing a seamless browsing experience for users. By leveraging go_router, developers can simplify the navigation setup process, handle authentication efficiently, and enhance the overall user experience.
By following the steps outlined in this article, you can easily set up go_router in your Flutter Web project, add necessary dependencies, create a common service for authentication logic, define routes, and design pages that provide a cohesive and intuitive user experience. For any assistance with Flutter app development, connect with our team of skilled Flutter developers today. They will provide expert guidance and deliver top-notch solutions tailored to your needs.
If you enjoyed this blog, you might also be interested in our post on optimizing paginated list fetching in Flutter using the generic BLoC pattern.