# Expo Router di React Native: Panduan Lengkap Navigasi Berbasis File
> Expo Router menghadirkan sistem routing berbasis file ke React Native, terinspirasi dari Next.js. Panduan lengkap mencakup konfigurasi, navigasi tab, rute dinamis, modal, middleware, dan proteksi rute.
- Published: 2026-04-18
- Updated: 2026-04-18
- Author: SharpSkill
- Tags: react-native, expo, expo-router, navigation, mobile-development, tutorial
- Reading time: 9 min
---
Expo Router mengubah cara pengelolaan navigasi dalam aplikasi React Native dengan mengadopsi sistem routing berbasis file yang terinspirasi langsung dari Next.js. Sejak hadirnya SDK Expo 55 dan Expo Router v6, konfigurasi navigator secara manual tidak lagi diperlukan. Cukup dengan membuat sebuah file di dalam direktori `app`, layar baru langsung tersedia sebagai rute. Android, iOS, dan web didukung secara seragam tanpa konfigurasi tambahan. Pendekatan ini secara signifikan menekan kompleksitas proyek lintas platform dan mempercepat siklus pengembangan aplikasi mobile.
> **Memulai dengan Cepat**
>
> Proyek Expo baru sudah menyertakan Expo Router secara default. Perintah `npx create-expo-app@latest --template default@sdk-55` menghasilkan proyek yang telah dikonfigurasi dengan routing berbasis file. Untuk proyek yang sudah ada, cukup instal package `expo-router` dan perbarui entry point aplikasi.
## Cara Kerja Routing Berbasis File di Expo Router
Setiap file yang ditempatkan di dalam direktori `app` secara otomatis menjadi sebuah rute. Jalur file berkorespondensi langsung dengan jalur URL, sehingga menghilangkan kebutuhan akan file konfigurasi terpusat. File `app/settings.tsx` menciptakan rute `/settings`, sedangkan `app/profile/edit.tsx` berkorespondensi dengan `/profile/edit`.
Konvensi ini menawarkan tiga keunggulan utama dibandingkan konfigurasi tradisional menggunakan React Navigation:
- **Tanpa konfigurasi**: rute terbentuk secara otomatis begitu file dibuat
- **Deep linking otomatis**: setiap layar memiliki URL tersendiri, memudahkan proses berbagi dan pengujian
- **Navigasi bertipe**: TypeScript mengenali rute yang tersedia sejak tahap kompilasi
```typescript
// app/index.tsx
import { View, Text, StyleSheet } from 'react-native'
import { Link } from 'expo-router'
export default function HomeScreen() {
return (
Welcome
{/* Link maps directly to file path */}
Open Settings
Edit Profile
)
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', padding: 24 },
title: { fontSize: 28, fontWeight: 'bold', marginBottom: 16 },
link: { fontSize: 16, color: '#61DAFB', marginTop: 12 },
})
```
Komponen `Link` menangani navigasi di semua platform. Di web, komponen ini menghasilkan elemen anchor dengan atribut `href` yang sesuai untuk keperluan SEO. Di platform native, komponen ini memicu navigasi bertipe stack.
## Struktur Proyek dan File Layout
Expo Router menggunakan file `_layout.tsx` untuk mendefinisikan kontainer navigasi. Setiap direktori dapat memiliki layout-nya sendiri, sehingga memungkinkan terciptanya hierarki navigasi bersarang. Layout root membungkus keseluruhan aplikasi, sementara layout bersarang mengontrol bagian-bagian tertentu.
Berikut adalah struktur proyek yang umum digunakan:
```text
app/
_layout.tsx # Root layout (Stack or custom)
index.tsx # Home screen (/)
(tabs)/ # Tab group (parentheses = route group)
_layout.tsx # Tab navigator
home.tsx # /home tab
search.tsx # /search tab
profile.tsx # /profile tab
settings/
_layout.tsx # Settings stack layout
index.tsx # /settings
notifications.tsx # /settings/notifications
privacy.tsx # /settings/privacy
```
Grup rute -- direktori yang diapit tanda kurung -- berfungsi untuk mengelompokkan file tanpa memengaruhi URL. Direktori `(tabs)` di atas membentuk navigator tab, namun URL tetap menjadi `/home`, `/search`, dan `/profile`, bukan `/tabs/home`.
```typescript
// app/_layout.tsx
import { Stack } from 'expo-router'
export default function RootLayout() {
return (
)
}
```
Layout root juga berperan sebagai titik inisialisasi untuk pemuatan font, pengaturan provider, dan konfigurasi global lainnya. File ini menggantikan `App.tsx` tradisional sebagai entry point aplikasi.
## Membangun Navigasi Tab
Navigasi tab memerlukan file `_layout.tsx` di dalam sebuah grup rute. Expo Router v6 memperkenalkan `NativeTabs` untuk pengalaman native yang spesifik per platform, namun komponen standar `Tabs` sudah mencakup sebagian besar kebutuhan.
```typescript
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router'
import { Ionicons } from '@expo/vector-icons'
export default function TabLayout() {
return (
(
),
}}
/>
(
),
}}
/>
(
),
}}
/>
)
}
```
Setiap file layar tab mengekspor komponen React standar. Ikon, label, dan badge pada tab bar dikonfigurasi melalui prop `options` di layout.
## Rute Dinamis dan Parameter Rute
Segmen dinamis menggunakan tanda kurung siku pada nama file. File bernama `[id].tsx` mencocokkan satu segmen, sedangkan `[...slug].tsx` menangkap seluruh segmen yang tersisa pada jalur URL.
```typescript
// app/product/[id].tsx
import { View, Text, StyleSheet } from 'react-native'
import { useLocalSearchParams, Stack } from 'expo-router'
export default function ProductScreen() {
// Extract the dynamic parameter from the URL
const { id } = useLocalSearchParams<{ id: string }>()
return (
Product DetailsID: {id}
)
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 24 },
heading: { fontSize: 24, fontWeight: 'bold', marginBottom: 8 },
id: { fontSize: 16, color: '#888' },
})
```
Mengakses `/product/42` akan menampilkan layar ini dengan variabel `id` bernilai `"42"`. Hook `useLocalSearchParams` menyediakan akses bertipe terhadap seluruh parameter rute.
Untuk rute catch-all, `[...slug].tsx` menangkap segmen jalur secara keseluruhan:
```typescript
// app/docs/[...slug].tsx
import { useLocalSearchParams } from 'expo-router'
export default function DocsScreen() {
// /docs/getting-started/installation → slug = ['getting-started', 'installation']
const { slug } = useLocalSearchParams<{ slug: string[] }>()
return
}
```
## Typed Routes: Keamanan pada Tahap Kompilasi
Expo Router secara otomatis menghasilkan tipe rute ketika fitur `typed routes` diaktifkan. Pemeriksaan ini mendeteksi tautan yang rusak pada tahap kompilasi, bukan saat aplikasi dijalankan.
Aktivasi dilakukan melalui file `app.json`:
```json
{
"expo": {
"experiments": {
"typedRoutes": true
}
}
}
```
Setelah diaktifkan, prop `href` pada komponen `Link` dan argumen pada `router.push()` hanya menerima string yang sesuai dengan rute yang valid:
```typescript
// app/checkout.tsx
import { router } from 'expo-router'
function handleCheckout(cartId: string) {
// TypeScript validates this route exists
router.push(`/product/${cartId}`)
// This would cause a compile error if /nonexistent doesn't exist
// router.push('/nonexistent')
}
```
Fitur typed routes bekerja sangat baik dengan `useLocalSearchParams`. Tipe yang dihasilkan menjamin kecocokan antara nama parameter pada definisi rute dan parameter yang digunakan oleh komponen pemanggil, sehingga mencegah bug halus yang baru muncul saat navigasi ke layar tertentu.
## Layar Modal dan Opsi Presentasi
Modal di Expo Router merupakan layar biasa yang dikonfigurasi dengan `presentation: 'modal'` pada layout. Pendekatan ini tetap menghormati konvensi routing berbasis file: modal pada dasarnya hanyalah sebuah rute seperti rute lainnya.
```typescript
// app/_layout.tsx
import { Stack } from 'expo-router'
export default function RootLayout() {
return (
{/* Modal screen slides up from the bottom */}
)
}
```
```typescript
// app/create-post.tsx
import { View, TextInput, Button, StyleSheet } from 'react-native'
import { router } from 'expo-router'
import { useState } from 'react'
export default function CreatePostModal() {
const [title, setTitle] = useState('')
const handleSubmit = () => {
// Submit logic here
router.back() // Dismiss the modal
}
return (
)
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 24 },
input: {
borderWidth: 1,
borderColor: '#333',
borderRadius: 8,
padding: 12,
fontSize: 16,
marginBottom: 16,
},
})
```
Mengakses `/create-post` akan memicu presentasi modal. Pemanggilan `router.back()` menutup modal dan mengembalikan pengguna ke layar sebelumnya dalam tumpukan navigasi.
## Navigasi Programatik dan API Router
Selain komponen `Link`, Expo Router menyediakan API imperatif melalui objek `router`. API ini memungkinkan pengelolaan navigasi yang dipicu oleh logika bisnis, bukan hanya oleh interaksi langsung pengguna.
```typescript
import { router } from 'expo-router'
// Push a new screen onto the stack
router.push('/profile/settings')
// Replace the current screen (no back button)
router.replace('/login')
// Go back to the previous screen
router.back()
// Navigate with parameters
router.push({
pathname: '/product/[id]',
params: { id: '42', source: 'recommendations' },
})
// Check if going back is possible
import { useRouter } from 'expo-router'
function BackButton() {
const router = useRouter()
return router.canGoBack() ? (