Routing adalah salah satu keputusan arsitektur Flutter yang dampaknya paling terasa di kemudian hari — tapi paling sering diambil tanpa pertimbangan yang cukup di awal proyek.
Saya pernah membangun proyek dengan Navigator.push() sederhana, lalu dua bulan kemudian dipaksa refactor total karena klien meminta deep linking. Pengalaman yang tidak menyenangkan. Sejak itu, saya selalu memilih solusi routing sebelum menulis widget pertama.
Artikel ini adalah perbandingan jujur antara GoRouter dan Navigator 2.0 berdasarkan pengalaman menggunakan keduanya di proyek production.
Masalah dengan Navigator 1.0
Navigator klasik — Navigator.push(), Navigator.pop(), Navigator.pushNamed() — sederhana dan intuitif untuk aplikasi kecil. Tapi ia punya keterbatasan fundamental yang muncul seiring kompleksitas:
Tidak ada URL yang berarti. Di web, URL adalah sesuatu yang bisa dibookmark, dishare, dan diketik langsung. Dengan Navigator 1.0, tidak ada konsep URL yang sesungguhnya — hanya stack halaman yang hanya ada di memori.
Deep linking yang rumit. Membuka halaman spesifik dari notifikasi push atau dari link eksternal membutuhkan kode boilerplate yang tidak kecil, dan mudah salah.
Tidak ada back button yang konsisten di web. Tombol back browser tidak terhubung dengan stack Navigator dengan cara yang predictable.
Navigator 2.0: Powerful tapi Verbose
Google memperkenalkan Navigator 2.0 (dengan API deklaratif) di Flutter 1.22. Konsepnya bagus: routing berbasis state, URL-aware, dan mendukung deep link secara native.
Implementasinya? Verbose sekali.
Untuk setup routing dasar yang mendukung deep link, Anda perlu mengimplementasikan RouterDelegate, RouteInformationParser, dan RouteInformationProvider. Ini tiga class abstrak yang masing-masing membutuhkan beberapa method untuk diimplementasikan.
Contoh minimal RouterDelegate sudah lebih dari 60 baris kode. Dan itu belum termasuk RouteInformationParser-nya.
Navigator 2.0 bukan untuk lemah hati. Ia memberikan kontrol total atas routing behavior, tapi dengan harga kompleksitas yang tinggi. Untuk tim besar dengan kebutuhan routing yang sangat kustom, ini mungkin worth it. Untuk proyek solo atau tim kecil, hampir pasti overkill.
GoRouter: Navigator 2.0 yang Manusiawi
GoRouter adalah package routing yang dibangun di atas Navigator 2.0, tapi menyembunyikan kompleksitasnya di balik API yang deklaratif dan bersih. Sejak versi Flutter 3.0, GoRouter sudah direkomendasikan secara resmi oleh tim Flutter.
Setup dasar GoRouter:
final _router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(
path: '/',
builder: (context, state) => const BerandaPage(),
),
GoRoute(
path: '/artikel/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return ArtikelDetailPage(id: id);
},
),
GoRoute(
path: '/pengaturan',
builder: (context, state) => const PengaturanPage(),
routes: [
GoRoute(
path: 'notifikasi',
builder: (context, state) => const NotifikasiPage(),
),
],
),
],
);
// Di MaterialApp:
MaterialApp.router(
routerConfig: _router,
)
Bersih, mudah dibaca, dan langsung mendukung:
- Path parameters (
:id) - Query parameters
- Nested routes
- Deep linking (otomatis)
- Back button handling yang benar di web dan Android
Fitur GoRouter yang Paling Sering Saya Gunakan
Redirect untuk autentikasi:
final _router = GoRouter(
redirect: (context, state) {
final sudahLogin = ref.read(authProvider).isLoggedIn;
final menujuLogin = state.matchedLocation == '/login';
if (!sudahLogin && !menujuLogin) return '/login';
if (sudahLogin && menujuLogin) return '/';
return null; // tidak redirect
},
routes: [...],
);
Ini menggantikan puluhan baris boilerplate yang biasanya diperlukan untuk menjaga halaman terproteksi. Setiap kali state autentikasi berubah, GoRouter otomatis mengevaluasi ulang redirect dan mengarahkan pengguna ke halaman yang tepat.
ShellRoute untuk persistent navigation bar:
ShellRoute(
builder: (context, state, child) {
return ScaffoldWithNavBar(child: child);
},
routes: [
GoRoute(path: '/beranda', builder: ...),
GoRoute(path: '/cari', builder: ...),
GoRoute(path: '/profil', builder: ...),
],
)
Navigasi tab yang persisten — bottom navigation bar tidak rebuild ketika berpindah tab. Ini adalah pola yang sangat umum di aplikasi mobile modern, dan GoRouter menanganinya dengan sangat elegan.
Kekurangan GoRouter yang Perlu Diketahui
Tidak ada yang sempurna, termasuk GoRouter. Beberapa keterbatasan yang perlu Anda ketahui sebelum memutuskan:
Passing data non-serializable antar halaman lebih rumit. Karena GoRouter berbasis URL, passing object yang kompleks (yang tidak bisa direpresentasikan dalam URL) membutuhkan solusi tambahan — biasanya melalui state management atau extras parameter.
Animasi transisi kustom membutuhkan setup tambahan. Untuk transisi default (slide dari kanan), GoRouter bekerja langsung. Untuk animasi transisi kustom per route, perlu menggunakan pageBuilder alih-alih builder biasa.
Debugging kompleks untuk aplikasi besar. Ketika ada banyak redirect yang saling berinteraksi, melacak kenapa aplikasi berakhir di halaman tertentu bisa membingungkan. GoRouter menyediakan debugLogDiagnostics: true yang sangat membantu untuk kasus ini.
Kapan Memilih Mana
Gunakan Navigator 1.0 sederhana ketika: Aplikasi kecil dengan 3–5 layar, tidak butuh deep linking, tidak akan pernah di-port ke web, dan kecepatan pengembangan adalah prioritas utama.
Gunakan GoRouter ketika: Hampir semua kondisi lainnya. Aplikasi dengan lebih dari 5 layar, butuh deep linking, ada persyaratan web, atau ada alur autentikasi yang perlu dikelola.
Gunakan Navigator 2.0 raw ketika: Anda membutuhkan kontrol routing yang tidak bisa diekspresikan dalam API GoRouter, dan Anda siap dengan kompleksitas implementasi yang menyertainya.
Kesimpulan
GoRouter adalah jawaban yang tepat untuk sebagian besar proyek Flutter modern. Ia memberikan semua keunggulan Navigator 2.0 — URL-awareness, deep linking, state-based routing — dengan kompleksitas implementasi yang jauh lebih masuk akal.
Investasikan 30 menit di awal proyek untuk setup GoRouter dengan benar. Anda akan bersyukur ketika enam bulan kemudian ada permintaan fitur yang membutuhkan deep linking, dan Anda tidak perlu menyentuh kode routing sama sekali.
Belum ada komentar. Jadilah yang pertama menulis.
Tulis Komentar