Interview frequency: …
Short answer
go_router defines a tree of routes by URL, turns the link into a stack of screens, and offers a central redirect that decides where the user goes based on sign-in state, with support for deep links and the web.
Explanation
The GoRouter is passed to MaterialApp.router. Nested routes are defined with parameters (such as product/:id), and the screen reads the parameters from state.pathParameters. The redirect function runs before the route is built and returns the alternative path or null for no redirect, and refreshListenable is used to re-evaluate when the sign-in state changes. Use context.go to replace the stack per the link, and context.push to place a screen on top of the current one. Take care that redirect rules do not produce an infinite loop.
Code example
final router = GoRouter(
initialLocation: '/',
refreshListenable: authState, // re-run redirect when the auth state changes
redirect: (context, state) {
final loggedIn = authState.isLoggedIn;
final onLogin = state.matchedLocation == '/login';
if (!loggedIn && !onLogin) return '/login';
if (loggedIn && onLogin) return '/';
return null; // no redirect
},
routes: [
GoRoute(
path: '/',
builder: (context, state) => const HomePage(),
routes: [
GoRoute(
path: 'product/:id',
builder: (context, state) => ProductPage(id: state.pathParameters['id']!),
),
],
),
GoRoute(path: '/login', builder: (context, state) => const LoginPage()),
],
);
// MaterialApp.router(routerConfig: router);
// context.go('/product/42'); // rebuilds the stack for this URL
// context.push('/product/42'); // pushes on top of the current stackCommon mistakes
- Writing redirect logic that sends the user to a route which in turn sends them back to the first route, creating an infinite loop.
- Using context.go when you mean to go back to the previous screen, which replaces the stack and loses the expected back button.