React Native'de Expo Router: Dosya Tabanlı Navigasyon Rehberi
Expo Router ile React Native navigasyonunu öğrenin: dosya tabanlı yönlendirme, layoutlar, dinamik rotalar, tipli navigasyon ve modal, sekme gibi gelişmiş desenler.

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 57 ve Expo Router 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 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.
Expo Router ile Sekme Navigasyonu Oluşturma
Sekme navigasyonu, bir rota grubu içinde _layout.tsx dosyası gerektirir. Expo Router, platforma özgü sekme deneyimleri için hem NativeTabs bileşenini hem de çoğu kullanım senaryosunu karşılayan standart Tabs bileşenini sunar. SDK 56'dan itibaren Native Tabs, sekmenin görünür kalırken seçilmesini engelleyen disabled özelliğini destekler.
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, React Native 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, 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.
SDK 56 Geçişi: React Navigation Fork'u
Expo SDK 56 ile birlikte Expo Router artık @react-navigation/* paketlerine bağımlı değildir. Proje doğrudan React Navigation'dan import ediyorsa, import'lar güncellenmelidir:
| Orijinal Paket | Yeni Konum |
|---|---|
@react-navigation/native | expo-router/react-navigation |
@react-navigation/stack | expo-router/js-stack |
@react-navigation/bottom-tabs | expo-router/js-tabs |
Import'ları otomatik olarak güncellemek için codemod kullanılabilir:
npx expo-codemod sdk-56-expo-router-react-navigation-replace srcÇalışma zamanı API'si değişmeden kalır. Yalnızca modül belirteçleri taşınmıştır. @react-navigation/core paketinden import eden üçüncü taraf kütüphaneler otomatik olarak çalışır, çünkü Expo CLI bu import'ları paketleme sırasında yeniden yazar.
Kaynaklar
- Expo Router Dokümantasyonu — resmi kılavuz ve API referansı
- Expo SDK 57 Changelog — güncel kararlı sürüm notları
- Expo Router v56 Blog Yazısı — React Navigation fork'u açıklaması
- SDK 55'ten 56'ya Geçiş Kılavuzu — import geçiş adımları
Mülakatlarda Expo Router Hakkında Beklenenler
- Expo Router,
appdizinindeki her dosyayı otomatik olarak bir rotaya eşler ve manuel navigasyon yapılandırmasını ortadan kaldırır _layout.tsxdosyaları ile tanımlanan layout'lar, 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
- Layout bileşenlerindeki istemci tarafı rota korumaları yerel platformlarda kimlik doğrulamayı yönetirken, sunucu middleware'i web'i kapsar
- SDK 56'dan itibaren
@react-navigation/*import'larıexpo-router/*karşılıklarına güncellenmelidir
React Native mimarisi ve mülakat hazırlığı hakkında daha fazla bilgi için native modüller modülüne bakılabilir.
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
React Native kodundaki hatayı bulabilir misin?
Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Yazan:
Anthony Fillion-MailletSharpSkill kurucusu
10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.
6 Ekim 2026 tarihinde güncellendi
Etiketler
Paylaş
İlgili makaleler

React Native Uygulama Geliştirme Rehberi 2026: Prodüksiyon Uygulamaları ve Mülakat Soruları
2026 yılında React Native ile prodüksiyon uygulamaları geliştirmenin kapsamlı rehberi. Expo SDK 56, EAS Build, Hermes V1, Yeni Mimari ve React Native geliştiricileri için mülakat hazırlığı.

React Native 0.84'te Hermes V1: Performans, Ön Derlenmiş Bytecode ve Mülakat Soruları
React Native 0.84'te Hermes V1 performans optimizasyonlarına derinlemesine bakış: bytecode ön derleme, Hades GC, bellek yönetimi ve mobil geliştiriciler için temel mülakat soruları.

React Native ve TypeScript 2026: Tip-Güvenli Mimari ve Mülakat Soruları
TypeScript, Codegen, TurboModule ve Strict TypeScript API ile tip-güvenli React Native uygulamaları oluşturma. Mimari pattern'ler, typed navigasyon, 0.87 toolchain gereksinimleri ve mülakat sorularını kapsıyor.