
Learn how to implement Login and Register screens with GoRouter in Flutter. This tutorial covers setting up routing, handling navigation, and redirecting users based on authentication state.
GoRouter is a routing package in Flutter that helps manage app navigation with a declarative API. It’s a modern, powerful, and flexible solution to handle complex routes, nested routes, redirections, and more.
In this guide, we’ll create a basic Flutter app using GoRouter to handle Login and Register screens, showcasing how to use GoRouter for a simple authentication.
Table of Contents
Setting Up GoRouter in Flutter
Before we dive into the code, let’s set up GoRouter in a Flutter project.
- Add GoRouter dependency to your
pubspec.yaml:
dependencies:
flutter:
sdk: flutter
go_router: ^5.0.0
- Run
flutter pub getto fetch the dependencies.
Basic Project Structure
Let’s create a simple project structure with the following screens:
- LoginScreen: A screen where users can log in.
- RegisterScreen: A screen where users can register a new account.
- HomeScreen: A screen that users see after successfully logging in.
For simplicity, we won’t include an actual backend; instead, we’ll simulate user authentication in memory.
Step-by-Step Example with GoRouter
Lets go through each step to implement Login and Register screens with GoRouter in Flutter.
1. Create Login Screen
This screen will allow users to log in. We’ll simulate a successful login and navigate the user to the HomeScreen.
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Login')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
decoration: InputDecoration(labelText: 'Email'),
),
TextField(
obscureText: true,
decoration: InputDecoration(labelText: 'Password'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Simulate successful login
context.go('/home');
},
child: Text('Login'),
),
TextButton(
onPressed: () {
context.go('/register');
},
child: Text('Don\'t have an account? Register'),
),
],
),
),
);
}
}
2. Create Register Screen
This screen will allow users to create an account. Upon successful registration, the user is redirected to the LoginScreen.
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class RegisterScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Register')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
decoration: InputDecoration(labelText: 'Email'),
),
TextField(
obscureText: true,
decoration: InputDecoration(labelText: 'Password'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Simulate successful registration
context.go('/login');
},
child: Text('Register'),
),
TextButton(
onPressed: () {
context.go('/login');
},
child: Text('Already have an account? Login'),
),
],
),
),
);
}
}
3. Create Home Screen
After a successful login, users will be redirected to the HomeScreen, which will simply display a welcome message.
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: Center(
child: Text('Welcome to the Home Screen!'),
),
);
}
}
4. Set Up GoRouter
Now, let’s configure GoRouter to handle the navigation between the screens.
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'login_screen.dart';
import 'register_screen.dart';
import 'home_screen.dart';
void main() {
final GoRouter _router = GoRouter(
initialLocation: '/login',
routes: [
// Login route
GoRoute(
path: '/login',
builder: (context, state) => LoginScreen(),
),
// Register route
GoRoute(
path: '/register',
builder: (context, state) => RegisterScreen(),
),
// Home route (requires successful login)
GoRoute(
path: '/home',
builder: (context, state) => HomeScreen(),
),
],
// Redirect based on some condition (e.g., logged-in state)
redirect: (state) {
// Simulate redirect if the user is already logged in
bool isLoggedIn = false; // Modify this based on your actual auth logic
final goingToLogin = state.location == '/login';
if (isLoggedIn && goingToLogin) {
return '/home'; // Redirect to home if already logged in
}
return null; // No redirect needed
},
);
runApp(MyApp(router: _router));
}
class MyApp extends StatelessWidget {
final GoRouter router;
const MyApp({Key? key, required this.router}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'GoRouter Example',
routerConfig: router,
);
}
}
Explanation of the Code
- GoRouter Configuration: In the
GoRouterconstructor, we define routes for the Login, Register, and Home screens. TheinitialLocationis set to/loginso the login screen is shown first when the app is launched. - Redirect Logic: We simulate a basic
redirectlogic, which prevents users from navigating to the LoginScreen if they are already logged in. In this example, we setisLoggedIntofalse, but you can replace it with actual authentication logic (such as checking the user’s login state from shared preferences or a session). - Navigation with
context.go(): Thecontext.go()method is used to navigate to different routes. When a user successfully logs in or registers, we navigate them to the appropriate screen.
Testing the Application
- Login Screen: The user can enter credentials (though it’s just a simulation here) and navigate to the HomeScreen upon success.
- Register Screen: The user can register a new account and will be redirected to the LoginScreen.
- Home Screen: After successful login, users are shown a welcome message.
Conclusion
This simple example demonstrates how to use GoRouter to handle navigation between Login, Register, and Home screens in a Flutter app. By leveraging GoRouter’s features, you can create a clean, structured, and flexible routing system in your application.
You can extend this basic example by incorporating real authentication, managing login state with packages like provider or riverpod, and handling more complex navigation flows.
Let me know if you need further clarification or additional examples!







