React Native'de Expo Router: Dosya Tabanlı Navigasyon Rehberi
React Native'de Expo Router ile dosya tabanlı navigasyon rehberi — dinamik rotalar, sekme navigasyonu, modal ekranlar ve rota koruması. 2026 güncel kaynak.

Expo Router, React Native uygulamalarına dosya tabanlı yönlendirme getirerek manuel navigasyon yapılandırmasını Next.js'den ilham alan konvansiyon tabanlı bir yaklaşımla değiştiriyor. Expo SDK 55 ve Expo Router v6 ile birlikte Android, iOS ve web platformları için çapraz platform navigasyonu oluşturmak, dosyaları doğru dizinde oluşturmaktan ibaret hale geliyor.
Yeni Expo projeleri, Expo Router önceden yapılandırılmış olarak gelir. Dosya tabanlı yönlendirme ile başlamak için npx create-expo-app@latest --template default@sdk-55 komutunu çalıştırmak yeterlidir. Mevcut projelere expo-router paketi kurulup giriş noktası güncellenerek eklenebilir.
Expo Router'da Dosya Tabanlı Yönlendirme Nasıl Çalışır
app dizini içindeki her dosya otomatik olarak bir rota haline gelir. Dosya yolu doğrudan URL yoluna eşlenir ve merkezi bir navigasyon yapılandırması ihtiyacını ortadan kaldırır. app/settings.tsx dosyası /settings rotasını oluştururken, app/profile/edit.tsx dosyası /profile/edit rotasına eşlenir.
Bu yaklaşım, geleneksel React Navigation kurulumuna kıyasla üç temel avantaj sunar:
- Sıfır yapılandırma: rotalar dosya oluşturulduğu anda var olur
- Otomatik deep linking: her ekran bir URL alır, paylaşım ve test imkanı sağlar
- Tip güvenli navigasyon: TypeScript, derleme zamanında hangi rotaların mevcut olduğunu bilir
import { View, Text, StyleSheet } from 'react-native'
import { Link } from 'expo-router'
export default function HomeScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>Welcome</Text>
{/* Link maps directly to file path */}
<Link href="/settings" style={styles.link}>
Open Settings
</Link>
<Link href="/profile/edit" style={styles.link}>
Edit Profile
</Link>
</View>
)
}
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 },
})Link bileşeni tüm platformlarda navigasyonu yönetir. Web'de SEO için uygun href özelliklerine sahip bir <a> etiketi olarak render edilir. Yerel platformlarda ise yığın tabanlı navigasyonu tetikler.
Proje Yapısı ve Layout Dosyaları
Expo Router, navigasyon konteynerlerini tanımlamak için _layout.tsx dosyalarını kullanır. Her dizin kendi layout dosyasına sahip olabilir ve iç içe geçmiş navigasyon hiyerarşileri oluşturulabilir. Kök layout tüm uygulamayı sararken, iç içe geçmiş layout'lar belirli bölümleri kontrol eder.
Tipik bir proje yapısı şu şekildedir:
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/privacyRota grupları — parantez içine alınmış dizinler — URL'yi etkilemeden dosyaları düzenler. Yukarıdaki (tabs) dizini bir sekme navigatörü oluşturur, ancak URL'ler /tabs/home yerine /home, /search ve /profile olarak kalır.
import { Stack } from 'expo-router'
export default function RootLayout() {
return (
<Stack
screenOptions={{
headerStyle: { backgroundColor: '#1a1a2e' },
headerTintColor: '#ffffff',
headerTitleStyle: { fontWeight: '600' },
}}
>
<Stack.Screen name="index" options={{ title: 'Home' }} />
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="settings" options={{ title: 'Settings' }} />
</Stack>
)
}Kök layout aynı zamanda fontların yüklenmesi, sağlayıcıların başlatılması ve genel ayarların yapılandırılması için kullanılan yerdir — geleneksel App.tsx giriş noktasının yerini alır.
Expo Router ile Sekme Navigasyonu Oluşturma
Sekme navigasyonu, bir rota grubu içinde _layout.tsx dosyası gerektirir. Expo Router v6, platforma özgü sekme deneyimleri için NativeTabs bileşenini sunar, ancak standart Tabs bileşeni çoğu kullanım senaryosunu karşılar.
import { Tabs } from 'expo-router'
import { Ionicons } from '@expo/vector-icons'
export default function TabLayout() {
return (
<Tabs
screenOptions={{
tabBarActiveTintColor: '#61DAFB',
tabBarInactiveTintColor: '#888',
tabBarStyle: {
backgroundColor: '#1a1a2e',
borderTopColor: '#2d2d44',
},
}}
>
<Tabs.Screen
name="home"
options={{
title: 'Home',
tabBarIcon: ({ color, size }) => (
<Ionicons name="home" size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="search"
options={{
title: 'Search',
tabBarIcon: ({ color, size }) => (
<Ionicons name="search" size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Profile',
tabBarIcon: ({ color, size }) => (
<Ionicons name="person" size={size} color={color} />
),
}}
/>
</Tabs>
)
}Her sekme ekranı dosyası standart bir React bileşeni dışa aktarır. Sekme çubuğu simgesi, etiketi ve rozeti, layout dosyasındaki options özelliği aracılığıyla yapılandırılır.
Dinamik Rotalar ve Rota Parametreleri
Dinamik segmentler, dosya adında köşeli parantez kullanır. [id].tsx adlı bir dosya tek bir segmentle eşleşirken, [...slug].tsx kalan tüm segmentleri yakalar.
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 (
<View style={styles.container}>
<Stack.Screen options={{ title: `Product ${id}` }} />
<Text style={styles.heading}>Product Details</Text>
<Text style={styles.id}>ID: {id}</Text>
</View>
)
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 24 },
heading: { fontSize: 24, fontWeight: 'bold', marginBottom: 8 },
id: { fontSize: 16, color: '#888' },
})/product/42 adresine gidildiğinde bu ekran id değeri "42" olarak render edilir. useLocalSearchParams hook'u, tüm rota parametrelerine tipli erişim sağlar.
Tüm segmentleri yakalayan (catch-all) rotalar için [...slug].tsx dosyası kullanılır:
import { useLocalSearchParams } from 'expo-router'
export default function DocsScreen() {
// /docs/getting-started/installation → slug = ['getting-started', 'installation']
const { slug } = useLocalSearchParams<{ slug: string[] }>()
return <DocViewer path={slug.join('/')} />
}React Native mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Derleme Zamanı Güvenliği İçin Tipli Rotalar
Expo Router, typed routes özelliği etkinleştirildiğinde rota tiplerini otomatik olarak oluşturur. Bu sayede bozuk bağlantılar çalışma zamanı yerine derleme zamanında tespit edilir.
Tipli rotaları app.json dosyasında etkinleştirmek için:
{
"expo": {
"experiments": {
"typedRoutes": true
}
}
}Etkinleştirildikten sonra Link bileşenindeki href özelliği ve router.push() argümanı yalnızca geçerli rota dizelerini kabul eder:
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')
}Tipli rotalar, useLocalSearchParams ile mükemmel uyum sağlar. Oluşturulan tipler, rota tanımı ile bu rotayı kullanan bileşen arasındaki parametre adlarının eşleşmesini garanti eder ve yalnızca belirli bir ekrana gidildiğinde ortaya çıkacak ince hataları önler.
Modal Ekranlar ve Sunum Seçenekleri
Expo Router'da modaller, layout dosyasında presentation: 'modal' ile yapılandırılmış normal ekranlardır. Bu yaklaşım dosya tabanlı konvansiyonu korur — modal yalnızca başka bir rotadır.
import { Stack } from 'expo-router'
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="index" />
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
{/* Modal screen slides up from the bottom */}
<Stack.Screen
name="create-post"
options={{
presentation: 'modal',
headerTitle: 'New Post',
}}
/>
</Stack>
)
}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 (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Post title"
value={title}
onChangeText={setTitle}
/>
<Button title="Publish" onPress={handleSubmit} />
</View>
)
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 24 },
input: {
borderWidth: 1,
borderColor: '#333',
borderRadius: 8,
padding: 12,
fontSize: 16,
marginBottom: 16,
},
})/create-post adresine gidildiğinde modal sunum tetiklenir. router.back() çağrısı modali kapatarak yığındaki önceki ekrana döner.
Programatik Navigasyon ve Router API
Link bileşeninin ötesinde, Expo Router, router nesnesi aracılığıyla imperatif bir API sunar. Bu API, kullanıcı dokunuşları yerine iş mantığı tarafından tetiklenen navigasyonu yönetir.
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() ? (
<Button title="Back" onPress={() => router.back()} />
) : null
}router.push ve router.replace arasındaki fark, kimlik doğrulama akışlarında önem kazanır. Başarılı bir giriş sonrasında router.replace('/dashboard') kullanılması, kullanıcının giriş ekranına geri dönmesini engeller.
router.replace() navigasyon geçmişindeki mevcut girdiyi değiştirir. Kimliği doğrulanmamış kullanıcıları yönlendiren koruma mekanizmalarında, bileşen render'ı içinde <Redirect href="/login" /> kullanılmalıdır — render aşamasında tetiklenir ve sunucu tarafı render ile doğru şekilde çalışır.
Middleware ve Rota Koruması
Expo Router v6, rota düzeyinde mantık için sunucu middleware'i sunar. +middleware.ts dosyası, istekleri rota bileşenine ulaşmadan önce yakalar ve kimlik doğrulama kontrolleri, yönlendirmeler ve başlık manipülasyonu sağlar.
import { type MiddlewareRequest } from 'expo-router/server'
export function middleware(request: MiddlewareRequest) {
const { pathname } = request.nextUrl
// Protect dashboard routes
const protectedPaths = ['/dashboard', '/settings', '/profile']
const isProtected = protectedPaths.some(p => pathname.startsWith(p))
if (isProtected) {
const token = request.cookies.get('session')
if (!token) {
return Response.redirect(new URL('/login', request.url))
}
}
return undefined // Continue to route
}Sunucu middleware'inin çalışmadığı yerel platformlarda rota koruması istemci tarafı korumalarına dayanır. Yaygın bir desen, korunan layout'ları kimlik doğrulama kontrolüyle sarar:
import { Redirect, Stack } from 'expo-router'
import { useAuth } from '@/hooks/useAuth'
export default function AuthenticatedLayout() {
const { isLoggedIn, isLoading } = useAuth()
if (isLoading) return null
if (!isLoggedIn) return <Redirect href="/login" />
return <Stack />
}Sunucu middleware'i yalnızca sunucu tarafı render ile web'de çalışır. Yerel uygulamalar için layout bileşenlerinde her zaman istemci tarafı rota korumaları uygulanmalıdır. Her iki yaklaşımın birleştirilmesi, tüm platformlarda tutarlı koruma sağlar.
Sonuç
- Expo Router v6, manuel navigasyon yapılandırmasını dosya tabanlı konvansiyonlarla değiştirerek
appdizinindeki her dosyayı otomatik olarak bir rotaya eşler _layout.tsxdosyaları ile tanımlanan layout'lar, merkezi yapılandırma olmadan yığın, sekme ve çekmece navigasyon hiyerarşileri oluşturur[param].tsxile dinamik rotalar ve[...slug].tsxile catch-all rotalar, tam TypeScript desteğiyle parametreli navigasyonu yönetir- Tipli rotalar,
app.jsondosyasında etkinleştirildiğinde bozuk navigasyon bağlantılarını derleme zamanında yakalar - Modal ekranlar,
router.push/replace/backile programatik navigasyon ve sunucu middleware'i yönlendirme araç setini tamamlar - Parantezli dizinlerle oluşturulan rota grupları, URL'leri etkilemeden kodu düzenler ve uygulama büyüdükçe dosya ağacını temiz tutar
- Layout bileşenlerindeki istemci tarafı rota korumaları yerel platformlarda kimlik doğrulamayı yönetirken, sunucu middleware'i web'i kapsar — her iki yaklaşım birlikte çapraz platform uygulamaları için kullanılmalıdır
Etiketler
Paylaş
