DEV Community

Cover image for Understanding Flutter GoRouter for Beginners
Bestaoui Aymen
Bestaoui Aymen

Posted on

Understanding Flutter GoRouter for Beginners

What is GoRouter?

GoRouter is a powerful and flexible routing package for Flutter, developed by the Flutter team. It makes navigation in Flutter apps easier by providing a simple, declarative way to define routes and handle navigation. Unlike Flutter's default Navigator (which can be a bit complex for beginners), GoRouter uses a URL-based approach, similar to how websites work, making it intuitive and scalable.

Why Use GoRouter?

  • Simple Syntax: GoRouter lets you define routes using easy-to-understand code.
  • URL-Based Navigation: It supports web-like URLs (e.g., /home or /profile/123), which is great for web apps and deep linking.
  • Nested Routes: You can create nested navigation (like tabs or subtabs) easily.
  • Parameter Support: Pass data like IDs (e.g., /product/42) directly in the URL.
  • Redirects: Handle navigation logic, like redirecting users to a login page if they're not signed in.
  • Beginner-Friendly: It reduces the complexity of managing navigation stacks.

Setting Up GoRouter

Let’s walk through how to set up and use GoRouter in a Flutter app. We’ll create a simple app with two screens: a Home screen and a Profile screen.

Step 1: Add GoRouter to Your Project

First, you need to add the go_router package to your Flutter project. Open your pubspec.yaml file and add the following dependency:

dependencies:
  go_router: ^16.2.1
Enter fullscreen mode Exit fullscreen mode

Then, run flutter pub get in your terminal to install the package. (Note: The version number might change, so check pub.dev for the latest version.)

Step 2: Create Your Screens

Let’s create two simple screens for our app: HomeScreen and ProfileScreen.

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Welcome to the Home Screen!'),
            ElevatedButton(
              onPressed: () {
                // We'll navigate to the Profile screen later
              },
              child: const Text('Go to Profile'),
            ),
          ],
        ),
      ),
    );
  }
}

class ProfileScreen extends StatelessWidget {
  final String? userId; // Optional parameter for user ID
  const ProfileScreen({super.key, this.userId});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Profile')),
      body: Center(
        child: Text('Profile Screen${userId != null ? ' for User $userId' : ''}'),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Set Up GoRouter

Now, let’s configure GoRouter to handle navigation between these screens. In your main.dart, set up the router and define the routes.

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

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

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

  // Define the GoRouter configuration
  final GoRouter _router = GoRouter(
    routes: [
      GoRoute(
        path: '/', // Root route (Home screen)
        builder: (context, state) => const HomeScreen(),
      ),
      GoRoute(
        path: '/profile/:userId', // Profile route with a parameter
        builder: (context, state) {
          final userId = state.pathParameters['userId'];
          return ProfileScreen(userId: userId);
        },
      ),
    ],
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Flutter GoRouter Demo',
      routerConfig: _router, // Use GoRouter for navigation
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation of the Code

  • GoRouter Configuration: We create a GoRouter instance and define two routes:
    • /: The root route, which shows the HomeScreen.
    • /profile/:userId: A route for the ProfileScreen with a dynamic userId parameter (e.g., /profile/123).
  • MaterialApp.router: Instead of the usual MaterialApp, we use MaterialApp.router to integrate GoRouter.
  • Path Parameters: The :userId in /profile/:userId allows us to pass dynamic data, like a user ID, to the ProfileScreen.

Step 4: Add Navigation

Let’s update the HomeScreen to navigate to the ProfileScreen when the button is pressed. Modify the ElevatedButton in HomeScreen:

ElevatedButton(
  onPressed: () {
    context.go('/profile/123'); // Navigate to Profile with userId 123
  },
  child: const Text('Go to Profile'),
)
Enter fullscreen mode Exit fullscreen mode

Here, context.go('/profile/123') tells GoRouter to navigate to the /profile/123 route, passing 123 as the userId.

Step 5: Run the App

Run your app using flutter run. You should see:

  • The Home screen with a button.
  • Clicking the button takes you to the Profile screen, displaying “Profile Screen for User 123”.

Key GoRouter Features for Beginners

1. Navigating Between Screens

Use context.go() to navigate to a new route. For example:

context.go('/profile/456'); // Navigates to ProfileScreen with userId 456
Enter fullscreen mode Exit fullscreen mode

2. Going Back

To go back to the previous screen, use:

context.pop();
Enter fullscreen mode Exit fullscreen mode

Add a back button to the ProfileScreen’s body:

ElevatedButton(
  onPressed: () {
    context.pop();
  },
  child: const Text('Go Back'),
)
Enter fullscreen mode Exit fullscreen mode

3. Passing Parameters

You’ve already seen how to pass a userId in the route (/profile/:userId). You can access it in the builder using state.pathParameters['userId'].

4. Nested Routes

If your app has nested navigation (e.g., a dashboard with tabs), you can define subroutes. For example:

GoRoute(
  path: '/dashboard',
  builder: (context, state) => const DashboardScreen(),
  routes: [
    GoRoute(
      path: 'settings',
      builder: (context, state) => const SettingsScreen(),
    ),
  ],
)
Enter fullscreen mode Exit fullscreen mode

Now, /dashboard/settings will show the SettingsScreen as a subroute of the DashboardScreen.

5. Redirects

You can redirect users based on conditions, like sending them to a login page if they’re not authenticated:

final GoRouter _router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const HomeScreen(),
    ),
  ],
  redirect: (context, state) {
    bool isLoggedIn = false; // Replace with your auth logic
    if (!isLoggedIn && state.uri.toString() != '/login') {
      return '/login';
    }
    return null; // No redirect
  },
);
Enter fullscreen mode Exit fullscreen mode

Tips for Beginners

  • Start Simple: Begin with basic routes like we did above before exploring nested routes or redirects.
  • Use Descriptive Paths: Make your route paths clear, like /home or /profile, to keep your code readable.
  • Test Navigation: Always test your routes to ensure they work as expected, especially when passing parameters.
  • Read the Docs: The GoRouter documentation is beginner-friendly and has more examples.

Try experimenting with more routes or adding redirects to enhance your app. Happy coding!

Top comments (0)