본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 04. 29. 09:51

Flutter GoRouter 심화 — 중첩 네비게이션, 인증 가드 및 딥 링크

요약

이 기술 기사는 Flutter의 GoRouter 패키지를 활용하여 고급 네비게이션 패턴을 구현하는 방법을 심층적으로 다룹니다. 주요 내용으로는 하단 탭 바를 포함한 중첩 라우팅(ShellRoute) 설정, 사용자 인증 상태에 따라 경로를 자동으로 리디렉션하는 인증 가드(redirect), 그리고 URL의 경로 매개변수 및 쿼리 문자열을 처리하는 딥 링크 구현 방법이 소개됩니다. 이 패턴들을 통해 복잡하고 견고한 대규모 애플리케이션 네비게이션 구조를 구축할 수 있습니다.

핵심 포인트

  • ShellRoute를 사용하여 하단 내비게이션 바가 유지되는 중첩 라우팅 구조를 쉽게 구현할 수 있다.
  • GoRouter의 `redirect` 기능을 활용하여 인증 상태(로그인 여부)에 따라 사용자를 자동으로 로그인 페이지나 홈 화면으로 리디렉션하는 인증 가드를 구축할 수 있다.
  • `refreshListenable`과 스트림을 결합하여 백엔드 인증 상태 변화를 실시간으로 감지하고 라우터를 업데이트할 수 있다.
  • 경로 매개변수(`:postId`)와 쿼리 문자열(`?highlight=flutter`)을 활용하여 동적인 데이터가 필요한 상세 페이지(딥 링크)를 효과적으로 처리할 수 있다.

Flutter GoRouter 심화 — 중첩 네비게이션, 인증 가드, 그리고 딥 링크
기본을 넘어선 실용적인 GoRouter 패턴들.

ShellRoute 를 사용한 중첩 네비게이션
final router = GoRouter(
routes: [
ShellRoute(
builder: (context, state, child) => ScaffoldWithBottomNav(
child: child,
),
routes: [
GoRoute(
path: '/home',
builder: (c, s) => const HomePage(),
),
GoRoute(
path: '/search',
builder: (c, s) => const SearchPage(),
),
GoRoute(
path: '/profile',
builder: (c, s) => const ProfilePage(),
),
],
),
// Auth screen lives outside ShellRoute
GoRoute(
path: '/login',
builder: (c, s) => const LoginPage(),
),
],
);

class ScaffoldWithBottomNav extends StatelessWidget {
const ScaffoldWithBottomNav({required this.child, super.key});

final Widget child;

@override
Widget build(BuildContext context) {
return Scaffold(
body: child,
bottomNavigationBar: BottomNavigationBar(
onTap: (i) => switch (i) {
0 => context.go('/home'),
1 => context.go('/search'),
_ => context.go('/profile'),
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
],
),
);
}
}

Authentication Guard (redirect)
final router = GoRouter(
redirect: (context, state) {
final isLoggedIn = ref.read(authStateProvider).value != null;
final isOnLoginPage = state.matchedLocation == '/login';

if (!isLoggedIn && !isOnLoginPage) return '/login';
if (isLoggedIn && isOnLoginPage) return '/home';
return null; // no redirect

},
refreshListenable: GoRouterRefreshStream(
supabase.auth.onAuthStateChange.map((e) => e.session),
),
routes: [...],
);

// Utility that reacts to auth state changes in real time
class GoRouterRefreshStream extends ChangeNotifier {
GoRouterRefreshStream(Stream stream) {
sub = stream.listen(() => notifyListeners());
}

late final StreamSubscription _sub;

@override
void dispose() {
_sub.cancel();
super.dispose();
}
}

Deep Links: Path Parameters and Query Strings
// URL like /posts/123?highlight=flutter
GoRoute(
path: '/posts/:postId',
builder: (context, state) {
final postId = state.pathParameters['postId']!;
final highlight = state.uri.queryParameters['highlight'];
return PostDetailPage(postId: postId, highlight: highlight);
},
),

// Nested paths
GoRoute(
path: '/users/:userId',
builder: (c, s) => UserPage(userId: s.pathParameters['userId']!),
routes: [
GoRoute(
path: 'posts/:postId', // /users/:userId/posts/:postId
builder: (c, s) =>
UserPostPage(
userId: s.pathParameters['userId']!,
postId: s.pathParameters['postId']!,
),
),
],
),

Summary
ShellRoute → shared bottom nav layout (nested navigation)
redirect → auth guard (refreshListenable reacts to state changes)
pathParameters / queryParameters → extract data from the URL
Deep links → same routing for both web and mobile
Mastering GoRouter gives you unified control from URL design to auth flows.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
3

댓글

0