# Expo Router pour React Native : Guide Complet de la Navigation par Fichiers
> Expo Router apporte le routage basé sur les fichiers à React Native, inspiré de Next.js. Guide complet avec configuration, navigation par onglets, routes dynamiques, modales, middleware et protection des routes.
- 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 transforme la gestion de la navigation dans les applications React Native en adoptant un système de routage basé sur les fichiers, directement inspiré de Next.js. Avec le SDK Expo 55 et Expo Router v6, la configuration manuelle des navigateurs appartient au passé. Il suffit de créer un fichier dans le répertoire `app` pour qu'un écran devienne accessible. Android, iOS et le web sont pris en charge de manière unifiée, sans configuration supplémentaire. Cette approche réduit considérablement la complexité des projets multiplateforme et accélère le développement mobile.
> **Mise en route rapide**
>
> Les nouveaux projets Expo intègrent Expo Router par défaut. La commande `npx create-expo-app@latest --template default@sdk-55` génère un projet préconfiguré avec le routage par fichiers. Pour les projets existants, il suffit d'installer le package `expo-router` et de mettre à jour le point d'entrée de l'application.
## Fonctionnement du routage par fichiers dans Expo Router
Chaque fichier placé dans le répertoire `app` devient automatiquement une route. Le chemin du fichier correspond directement au chemin de l'URL, ce qui élimine toute nécessité d'un fichier de configuration centralisé. Un fichier `app/settings.tsx` crée la route `/settings`, tandis que `app/profile/edit.tsx` correspond à `/profile/edit`.
Cette convention offre trois avantages majeurs par rapport à la configuration traditionnelle avec React Navigation :
- **Zéro configuration** : les routes existent dès la création du fichier
- **Deep linking automatique** : chaque écran dispose d'une URL, facilitant le partage et les tests
- **Navigation typée** : TypeScript connaît les routes existantes dès la compilation
```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 },
})
```
Le composant `Link` gère la navigation sur toutes les plateformes. Sur le web, il génère une balise ancre avec les attributs `href` appropriés pour le référencement. Sur les plateformes natives, il déclenche une navigation de type stack.
## Structure du projet et fichiers de layout
Expo Router utilise des fichiers `_layout.tsx` pour définir les conteneurs de navigation. Chaque répertoire peut contenir son propre layout, créant ainsi des hiérarchies de navigation imbriquées. Le layout racine enveloppe l'ensemble de l'application, tandis que les layouts imbriqués contrôlent des sections spécifiques.
Voici une structure de projet typique :
```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
```
Les groupes de routes -- des répertoires entourés de parenthèses -- organisent les fichiers sans affecter l'URL. Le répertoire `(tabs)` ci-dessus crée un navigateur par onglets, mais les URL restent `/home`, `/search` et `/profile` plutôt que `/tabs/home`.
```typescript
// app/_layout.tsx
import { Stack } from 'expo-router'
export default function RootLayout() {
return (
)
}
```
Le layout racine sert également de point d'initialisation pour le chargement des polices, la configuration des providers et les réglages globaux. Il remplace le traditionnel `App.tsx` comme point d'entrée de l'application.
## Construction d'une navigation par onglets
La navigation par onglets nécessite un fichier `_layout.tsx` à l'intérieur d'un groupe de routes. Expo Router v6 introduit `NativeTabs` pour des expériences natives spécifiques à chaque plateforme, mais le composant standard `Tabs` couvre la plupart des cas d'utilisation.
```typescript
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router'
import { Ionicons } from '@expo/vector-icons'
export default function TabLayout() {
return (
(
),
}}
/>
(
),
}}
/>
(
),
}}
/>
)
}
```
Chaque fichier d'écran d'onglet exporte un composant React standard. L'icône, le libellé et le badge de la barre d'onglets se configurent via la prop `options` du layout.
## Routes dynamiques et paramètres de route
Les segments dynamiques utilisent des crochets dans le nom du fichier. Un fichier nommé `[id].tsx` correspond à un segment unique, tandis que `[...slug].tsx` capture tous les segments restants du chemin.
```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' },
})
```
Accéder à `/product/42` affiche cet écran avec la variable `id` définie sur `"42"`. Le hook `useLocalSearchParams` fournit un accès typé à l'ensemble des paramètres de route.
Pour les routes attrape-tout, `[...slug].tsx` capture des segments de chemin entiers :
```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
}
```
## Typage des routes pour une sécurité à la compilation
Expo Router génère automatiquement les types de routes lorsque la fonctionnalité `typed routes` est activée. Cette vérification détecte les liens cassés à la compilation plutôt qu'à l'exécution.
Activation dans le fichier `app.json` :
```json
{
"expo": {
"experiments": {
"typedRoutes": true
}
}
}
```
Une fois activé, la prop `href` du composant `Link` et l'argument de `router.push()` n'acceptent que des chaînes correspondant à des routes valides :
```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')
}
```
Le typage des routes fonctionne particulièrement bien avec `useLocalSearchParams`. Les types générés garantissent la correspondance entre les noms de paramètres dans la définition de la route et ceux utilisés par le composant consommateur, prévenant ainsi les bugs subtils qui ne se manifestent qu'à la navigation vers un écran spécifique.
## Écrans modaux et options de présentation
Les modales dans Expo Router sont des écrans classiques configurés avec `presentation: 'modal'` dans le layout. Cette approche respecte la convention du routage par fichiers : une modale reste simplement une route comme les autres.
```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,
},
})
```
Accéder à `/create-post` déclenche la présentation modale. L'appel à `router.back()` la ferme et ramène l'utilisateur à l'écran précédent dans la pile de navigation.
## Navigation programmatique et API du routeur
Au-delà du composant `Link`, Expo Router fournit une API impérative via l'objet `router`. Celle-ci permet de gérer la navigation déclenchée par la logique métier plutôt que par une interaction directe de l'utilisateur.
```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() ? (