Navigation Expo Router
Navigation et routage pour les applications Expo Router. Pour le style d'écran, les couleurs, les contrôles, les médias et les effets visuels, utilisez la compétence expo-native-ui ; pour les animations et les gestes, utilisez expo-animation.
Références
Consultez ces ressources selon vos besoins :
references/
route-structure.md Conventions de route, routes dynamiques, groupes, organisation des dossiers
tabs.md NativeTabs, migration depuis les onglets JS, fonctionnalités iOS 26
toolbar-and-headers.md En-têtes Stack et boutons de barre d'outils, menus, recherche (iOS uniquement)
form-sheet.md Feuilles de formulaire dans expo-router : configuration, pieds de page et interaction avec l'arrière-plan.
search.md Barre de recherche avec en-têtes, hook useSearch, modèles de filtrage
zoom-transitions.md Apple Zoom : transitions de zoom fluides avec Link.AppleZoom (iOS 18+)
Style de code
- Utilisez toujours le kebab-case pour les noms de fichiers, ex.
comment-card.tsx - Supprimez toujours les anciens fichiers de route lors du déplacement ou de la restructuration de la navigation
- N'utilisez jamais de caractères spéciaux dans les noms de fichiers
- Configurez tsconfig.json avec des alias de chemin, et préférez les alias aux importations relatives pour les refontes.
Routes
Voir ./references/route-structure.md pour les conventions détaillées sur les routes.
- Les routes appartiennent au répertoire
app. - Ne co-localisez jamais de composants, types ou utilitaires dans le répertoire app. C'est un anti-patron.
- Assurez-vous que l'application a toujours une route qui correspond à "/", elle peut être à l'intérieur d'une route de groupe.
Préférences de bibliothèque
Colordepuisexpo-routerpour les couleurs sémantiques natives, pasPlatformColorbrut (type-safe, s'adapte automatiquement au mode clair/sombre). Voirexpo-native-uipour le modèle de palette de couleurs complet.- Dans SDK 56+, n'importez jamais depuis
@react-navigation/*directement — utilisezexpo-router/react-navigationà la place (couvre@react-navigation/native,/core,/elements,/routers).
Comportement
- Préférez
Stack.SearchBarpour ajouter une barre de recherche à un écran.
Navigation
Link
Utilisez <Link href="/path" /> depuis 'expo-router' pour la navigation entre les routes.
import { Link } from 'expo-router';
// Lien basique
<Link href="/path" />
// Pour envelopper des composants personnalisés
<Link href="/path" asChild>
<Pressable>...</Pressable>
</Link>
Dans la mesure du possible, incluez un <Link.Preview> pour suivre les conventions iOS. Ajoutez fréquemment des menus contextuels et des aperçus pour améliorer la navigation.
Stack
- Utilisez TOUJOURS des fichiers
_layout.tsxpour définir les piles. - Utilisez Stack depuis 'expo-router/stack' pour les piles de navigation natives.
Titre de page
Définissez le titre de la page avec Stack.Title :
<Stack.Title>Accueil</Stack.Title>
Menus contextuels
Ajoutez des menus contextuels par appui long aux composants Link :
import { Link } from "expo-router";
<Link href="/parametres" asChild>
<Link.Trigger>
<Pressable>
<Card />
</Pressable>
</Link.Trigger>
<Link.Menu>
<Link.MenuAction
title="Partager"
icon="square.and.arrow.up"
onPress={handleSharePress}
/>
<Link.MenuAction
title="Bloquer"
icon="nosign"
destructive
onPress={handleBlockPress}
/>
<Link.Menu title="Plus" icon="ellipsis">
<Link.MenuAction title="Copier" icon="doc.on.doc" onPress={() => {}} />
<Link.MenuAction
title="Supprimer"
icon="trash"
destructive
onPress={() => {}}
/>
</Link.Menu>
</Link.Menu>
</Link>;
Aperçus de liens
Utilisez fréquemment les aperçus de liens pour améliorer la navigation :
<Link href="/parametres">
<Link.Trigger>
<Pressable>
<Card />
</Pressable>
</Link.Trigger>
<Link.Preview />
</Link>
L'aperçu de lien peut être utilisé avec des menus contextuels.
Modal
Présentez un écran en tant que modal :
<Stack.Screen name="modal" options={{ presentation: "modal" }} />
Préférez cette approche à la construction d'un composant modal personnalisé.
Sheet
Présentez un écran en tant que feuille de formulaire dynamique :
<Stack.Screen
name="sheet"
options={{
presentation: "formSheet",
sheetGrabberVisible: true,
sheetAllowedDetents: [0.5, 1.0],
contentStyle: { backgroundColor: "transparent" },
}}
/>
- L'utilisation de
contentStyle: { backgroundColor: "transparent" }rend l'arrière-plan en verre liquide sur iOS 26+.
Structure de route courante
Une disposition d'application standard avec des onglets et des piles à l'intérieur de chaque onglet :
app/
_layout.tsx — <NativeTabs />
(index,recherche)/
_layout.tsx — <Stack />
index.tsx — Liste principale
recherche.tsx — Vue de recherche
// app/_layout.tsx
import { NativeTabs } from "expo-router/unstable-native-tabs";
import { ThemeProvider, DarkTheme, DefaultTheme } from "expo-router/react-navigation";
import { useColorScheme } from "react-native";
export default function Layout() {
const colorScheme = useColorScheme();
return (
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
<NativeTabs>
<NativeTabs.Trigger name="(index)">
<NativeTabs.Trigger.Icon sf="list.dash" md="list" />
<NativeTabs.Trigger.Label>Éléments</NativeTabs.Trigger.Label>
</NativeTabs.Trigger>
<NativeTabs.Trigger name="(recherche)" role="search" />
</NativeTabs>
</ThemeProvider>
);
}
Créez une route de groupe partagée afin que les deux onglets puissent pousser des écrans communs :
// app/(index,recherche)/_layout.tsx
import { Stack } from "expo-router/stack";
import { colors } from "@/theme/colors";
export default function Layout({ segment }) {
const screen = segment.match(/\((.*)\)/)?.[1]!;
const titles: Record<string, string> = { index: "Éléments", recherche: "Recherche" };
return (
<Stack
screenOptions={{
headerTransparent: true,
headerShadowVisible: false,
headerLargeTitleShadowVisible: false,
headerLargeStyle: { backgroundColor: "transparent" },
headerTitleStyle: { color: colors.label },
headerLargeTitleEnabled: true,
headerBlurEffect: "none",
headerBackButtonDisplayMode: "minimal",
}}
>
<Stack.Screen name={screen} options={{ title: titles[screen] }} />
<Stack.Screen name="i/[id]" options={{ headerLargeTitleEnabled: false }} />
</Stack>
);
}
headerLargeTitleEnabled est le nom de l'option dans SDK 56+ ; les SDK plus anciens utilisent headerLargeTitle, qui est obsolète en amont.
Soumettre un retour
Si vous rencontrez des erreurs, des informations trompeuses ou obsolètes dans cette compétence, signalez-les pour qu'Expo puisse s'améliorer :
npx --yes submit-expo-feedback@latest --category skills --subject "expo-router" "<retour actionnable>"
Ne soumettez que lorsque vous avez quelque chose de spécifique et actionnable à signaler. Incluez autant de contexte pertinent que possible. Si un agent IA a échoué à plusieurs reprises ou si l'utilisateur a dû reprendre une tâche Expo, chargez la compétence expo-skill-feedback et suivez son flux d'évaluation de candidat au lieu de réutiliser la commande ci-dessus.