Question

How do I write a GoRouter with login and home?

Answer and Explanation

To implement a GoRouter with login and home routes, you'll need to define your routes, handle authentication, and manage navigation based on the user's login status. Here's a comprehensive guide:

1. Set up GoRouter:

- First, ensure you have the `go_router` package added to your `pubspec.yaml` file. Then, create a `GoRouter` instance with your routes.

2. Define Routes:

- Define routes for your login page and home page. You might also have other routes, but these are the core ones for this example.

3. Implement Authentication Logic:

- Create a service or provider to manage the user's authentication state. This could involve checking for a token, user data, etc.

4. Use `redirect` Function:

- The `redirect` function in `GoRouter` is crucial. It allows you to intercept navigation and redirect the user based on their authentication status.

5. Example Code:

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

// Assume you have an AuthService to manage authentication
class AuthService extends ChangeNotifier {
  bool _isLoggedIn = false;
  bool get isLoggedIn => _isLoggedIn;

  void login() {
    _isLoggedIn = true;
    notifyListeners();
  }

  void logout() {
    _isLoggedIn = false;
    notifyListeners();
  }
}

// Define your routes
final _router = GoRouter(
  redirect: (context, state) {
    final authService = context.read<AuthService>();
    final isLoggedIn = authService.isLoggedIn;
    final isLoggingIn = state.location == '/login';

    if (!isLoggedIn && !isLoggingIn) {
      return '/login';
    }

    if (isLoggedIn && isLoggingIn) {
      return '/home';
    }

    return null;
  },
  routes: [
    GoRoute(
      path: '/login',
      builder: (context, state) => LoginPage(),
    ),
    GoRoute(
      path: '/home',
      builder: (context, state) => HomePage(),
    ),
  ],
);

// Example Login Page
class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            context.read<AuthService>().login();
            context.go('/home');
          },
          child: Text('Login'),
        ),
      ),
    );
  }
}

// Example Home Page
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            context.read<AuthService>().logout();
            context.go('/login');
          },
          child: Text('Logout'),
        ),
      ),
    );
  }
}

void main() {
  runApp(ChangeNotifierProvider(create: (_) => AuthService(), child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _router,
      title: 'GoRouter Example',
    );
  }
}

6. Explanation:

- The `AuthService` manages the login state. The `redirect` function checks if the user is logged in. If not, it redirects to `/login`. If the user is logged in and tries to access `/login`, it redirects to `/home`. The `LoginPage` and `HomePage` are simple widgets for demonstration.

7. Important Considerations:

- Use a state management solution (like Provider, Riverpod, or BLoC) to manage the authentication state effectively. Handle loading states and errors gracefully. Consider using a more robust authentication method (e.g., JWT). This example provides a basic structure; you'll need to adapt it to your specific needs.

More questions