expo-router

bởi expo

Khung mã nguồn mở. Điều hướng và định tuyến cho Expo Router. Bao gồm các tuyến dựa trên tệp, nhóm và tuyến động, tổ chức thư mục, Liên kết có xem trước và menu ngữ cảnh, Stack gốc, tiêu đề trang, modal và trang tính biểu mẫu, NativeTabs, tiêu đề và thanh công cụ, và thanh tìm kiếm tiêu đề.

npx skills add https://github.com/expo/skills --skill expo-router

Expo Router Navigation

Navigation and routing for Expo Router apps. For screen styling, colors, controls, animations, media, and visual effects, use the expo-native-ui skill.

References

Consult these resources as needed:

references/
  route-structure.md     Route conventions, dynamic routes, groups, folder organization
  tabs.md                NativeTabs, migration from JS tabs, iOS 26 features
  toolbar-and-headers.md Stack headers and toolbar buttons, menus, search (iOS only)
  form-sheet.md          Form sheets in expo-router: configuration, footers and background interaction.
  search.md              Search bar with headers, useSearch hook, filtering patterns
  zoom-transitions.md    Apple Zoom: fluid zoom transitions with Link.AppleZoom (iOS 18+)

Code Style

  • Always use kebab-case for file names, e.g. comment-card.tsx
  • Always remove old route files when moving or restructuring navigation
  • Never use special characters in file names
  • Configure tsconfig.json with path aliases, and prefer aliases over relative imports for refactors.

Routes

See ./references/route-structure.md for detailed route conventions.

  • Routes belong in the app directory.
  • Never co-locate components, types, or utilities in the app directory. This is an anti-pattern.
  • Ensure the app always has a route that matches "/", it may be inside a group route.

Library Preferences

  • Color from expo-router for native semantic colors, not raw PlatformColor (type-safe, auto-adapts to light/dark). See expo-native-ui for the full color palette pattern.
  • In SDK 56+, never import from @react-navigation/* directly — use expo-router/react-navigation instead (covers @react-navigation/native, /core, /elements, /routers)

Behavior

  • Prefer Stack.SearchBar to add a search bar to a screen

Navigation

Link

Use <Link href="/path" /> from 'expo-router' for navigation between routes.

import { Link } from 'expo-router';

// Basic link
<Link href="/path" />

// Wrapping custom components
<Link href="/path" asChild>
  <Pressable>...</Pressable>
</Link>

Whenever possible, include a <Link.Preview> to follow iOS conventions. Add context menus and previews frequently to enhance navigation.

Stack

  • ALWAYS use _layout.tsx files to define stacks
  • Use Stack from 'expo-router/stack' for native navigation stacks

Page Title

Set the page title with Stack.Title:

<Stack.Title>Home</Stack.Title>

Context Menus

Add long press context menus to Link components:

import { Link } from "expo-router";

<Link href="/settings" asChild>
  <Link.Trigger>
    <Pressable>
      <Card />
    </Pressable>
  </Link.Trigger>
  <Link.Menu>
    <Link.MenuAction
      title="Share"
      icon="square.and.arrow.up"
      onPress={handleSharePress}
    />
    <Link.MenuAction
      title="Block"
      icon="nosign"
      destructive
      onPress={handleBlockPress}
    />
    <Link.Menu title="More" icon="ellipsis">
      <Link.MenuAction title="Copy" icon="doc.on.doc" onPress={() => {}} />
      <Link.MenuAction
        title="Delete"
        icon="trash"
        destructive
        onPress={() => {}}
      />
    </Link.Menu>
  </Link.Menu>
</Link>;

Link Previews

Use link previews frequently to enhance navigation:

<Link href="/settings">
  <Link.Trigger>
    <Pressable>
      <Card />
    </Pressable>
  </Link.Trigger>
  <Link.Preview />
</Link>

Link preview can be used with context menus.

Modal

Present a screen as a modal:

<Stack.Screen name="modal" options={{ presentation: "modal" }} />

Prefer this to building a custom modal component.

Sheet

Present a screen as a dynamic form sheet:

<Stack.Screen
  name="sheet"
  options={{
    presentation: "formSheet",
    sheetGrabberVisible: true,
    sheetAllowedDetents: [0.5, 1.0],
    contentStyle: { backgroundColor: "transparent" },
  }}
/>
  • Using contentStyle: { backgroundColor: "transparent" } makes the background liquid glass on iOS 26+.

Common route structure

A standard app layout with tabs and stacks inside each tab:

app/
  _layout.tsx — <NativeTabs />
  (index,search)/
    _layout.tsx — <Stack />
    index.tsx — Main list
    search.tsx — Search view
// 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>Items</NativeTabs.Trigger.Label>
        </NativeTabs.Trigger>
        <NativeTabs.Trigger name="(search)" role="search" />
      </NativeTabs>
    </ThemeProvider>
  );
}

Create a shared group route so both tabs can push common screens:

// app/(index,search)/_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: "Items", search: "Search" };

  return (
    <Stack
      screenOptions={{
        headerTransparent: true,
        headerShadowVisible: false,
        headerLargeTitleShadowVisible: false,
        headerLargeStyle: { backgroundColor: "transparent" },
        headerTitleStyle: { color: colors.label },
        headerLargeTitle: true,
        headerBlurEffect: "none",
        headerBackButtonDisplayMode: "minimal",
      }}
    >
      <Stack.Screen name={screen} options={{ title: titles[screen] }} />
      <Stack.Screen name="i/[id]" options={{ headerLargeTitle: false }} />
    </Stack>
  );
}

Submitting Feedback

If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:

npx --yes submit-expo-feedback@latest --category skills --subject "expo-router" "<actionable feedback>"

Only submit when you have something specific and actionable to report. Include as much relevant context as possible.

Thêm skills từ expo

expo-upgrade
expo
Khung (Mã nguồn mở). Hướng dẫn nâng cấp phiên bản Expo SDK và sửa lỗi phụ thuộc
apidevelopmentofficial
expo-data-fetching
expo
Framework (OSS). Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, React Query, SWR, error handling, caching, offline support, and Expo Router data loaders (`useLoaderData`).
official
android-e2e-testing
expo
Kiểm tra các tính năng Expo Router trên trình giả lập Android bằng ADB. Sử dụng sau khi triển khai các tính năng Android gốc hoặc khi xác minh hành vi giao diện người dùng trên Android.
official
expo-dev-client
expo
Xây dựng các bản phát triển Expo tùy chỉnh để kiểm tra mã gốc trên thiết bị vật lý qua EAS Build hoặc cục bộ. Chỉ cần thiết khi sử dụng các mô-đun gốc tùy chỉnh, mục tiêu Apple (widget, app clips) hoặc mã gốc của bên thứ ba không có trong Expo Go; hãy thử Expo Go trước với lệnh npx expo start. Hỗ trợ xây dựng đám mây với tính năng tự động gửi lên TestFlight hoặc xây dựng cục bộ trên máy của bạn, xuất ra tệp .ipa (iOS) hoặc .apk / .aab (Android). Yêu cầu cấu hình eas.json với một hồ sơ phát triển thiết lập...
official
expo-tailwind-setup
expo
Kiểu dáng Tailwind CSS v4 phổ quát cho ứng dụng Expo trên iOS, Android và Web. Tích hợp Tailwind CSS v4 với react-native-css và NativeWind v5 thông qua Metro transformer, loại bỏ nhu cầu cấu hình Babel. Cung cấp thư viện component bọc CSS có thể tái sử dụng (View, Text, ScrollView, Pressable, TextInput, Image, Link) áp dụng className cho các phần tử gốc. Hỗ trợ kiểu dáng theo nền tảng thông qua truy vấn phương tiện CSS, biến theme tùy chỉnh qua khối @theme, và ngữ nghĩa Apple...
official
android-jetpack-compose
expo
Sử dụng khi xây dựng giao diện Android với Jetpack Compose, quản lý trạng thái bằng remember/mutableStateOf, hoặc triển khai các mẫu giao diện khai báo.
official
swiftui-expert-skill
expo
Viết, xem xét hoặc cải thiện mã SwiftUI theo các phương pháp tốt nhất về quản lý trạng thái, cấu trúc view, hiệu suất, API dành riêng cho macOS và iOS 26+ Liquid…
official
eas-update-insights
expo
Kiểm tra tình trạng của các bản cập nhật EAS đã phát hành: tỷ lệ sập, số lần cài đặt/khởi chạy, người dùng duy nhất, kích thước tải trọng và sự phân chia giữa người dùng nhúng và OTA theo…
official