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 (1)

Collapse
 
radon profile image
Robert Nebel

This example is sufficient—in other words, it shouldn't need to be any more complex to gain a basic understanding of ‘go_router’. This gives me the foundation I need to use this library. Thank you!