Agent Skills › expo/skills › expo-router

expo-router

GitHub

提供 Expo Router 应用的导航与路由开发指南,涵盖文件路由、动态路由、原生栈、标签页及链接组件的使用规范。

plugins/expo/skills/expo-router/SKILL.md expo/skills

Trigger Scenarios

需要配置 Expo Router 路由结构 实现页面间跳转或导航逻辑 调整原生栈、标签页或模态框布局

Install

npx skills add expo/skills --skill expo-router -g -y
More Options

Non-standard path

npx skills add https://github.com/expo/skills/tree/main/plugins/expo/skills/expo-router -g -y

Use without installing

npx skills use expo/skills@expo-router

指定 Agent (Claude Code)

npx skills add expo/skills --skill expo-router -a claude-code -g -y

安装 repo 全部 skill

npx skills add expo/skills --all -g -y

预览 repo 内 skill

npx skills add expo/skills --list

SKILL.md

Frontmatter
{
    "name": "expo-router",
    "license": "MIT",
    "description": "Navigation and routing for Expo Router. Covers file-based routes, groups and dynamic routes, folder organization, Link with previews and context menus, native Stack, page titles, modals and form sheets, NativeTabs, headers and toolbars, and header search bars."
}

Expo Router Navigation

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

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 },
        headerLargeTitleEnabled: true,
        headerBlurEffect: "none",
        headerBackButtonDisplayMode: "minimal",
      }}
    >
      <Stack.Screen name={screen} options={{ title: titles[screen] }} />
      <Stack.Screen name="i/[id]" options={{ headerLargeTitleEnabled: false }} />
    </Stack>
  );
}

headerLargeTitleEnabled is the SDK 56+ option name; older SDKs use headerLargeTitle, which is deprecated upstream.

Submitting Feedback

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

npx --yes @expo/agent-cli@latest feedback --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. If an agent repeatedly fails at an Expo task or the user has to step in, submit a brief report of the task, expected result, and what went wrong using --category evals and the relevant Expo package or command as --subject.

Version History

  • a9e5bd3 Current 2026-11-02 22:39

    移除了 SKILL.md 前置元数据中的版本键,并统一使用 agent CLI 进行反馈提交。

  • 7ddc1f5 2026-10-19 05:41

    移除技能描述前缀

  • 170589a 2026-09-09 05:12

    修正了关于动画和 API 使用的错误指引,统一了动画技能归属,并清理了过时的参考文档。

  • d1c68a2 2026-08-19 21:53
  • 09eb052 2026-07-24 22:02

Same Skill Collection

.claude/skills/expo-skill-eval/SKILL.md
plugins/expo-experiments/skills/expo-migrate-module/SKILL.md
plugins/expo/skills/eas-app-stores/SKILL.md
plugins/expo/skills/eas-update-insights/SKILL.md
plugins/expo/skills/eas-workflows/SKILL.md
plugins/expo/skills/expo-app-clip/SKILL.md
plugins/expo/skills/expo-brownfield/SKILL.md
plugins/expo/skills/expo-data-fetching/SKILL.md
plugins/expo/skills/expo-dev-client/SKILL.md
plugins/expo/skills/expo-dom/SKILL.md
plugins/expo/skills/expo-examples/SKILL.md
plugins/expo/skills/expo-module/SKILL.md
plugins/expo/skills/expo-native-ui/SKILL.md
plugins/expo/skills/expo-project-structure/SKILL.md
plugins/expo/skills/expo-tailwind-setup/SKILL.md
plugins/expo/skills/expo-upgrade/SKILL.md
plugins/expo/skills/expo-web-to-native/SKILL.md
plugins/expo/skills/eas-hosting/SKILL.md
plugins/expo/skills/eas-observe/SKILL.md
plugins/expo/skills/eas-simulator/SKILL.md
plugins/expo/skills/eas-update/SKILL.md
plugins/expo/skills/expo-animation/SKILL.md
plugins/expo/skills/expo-design-system/SKILL.md
plugins/expo/skills/expo-overview/SKILL.md
plugins/expo/skills/expo-skill-feedback/SKILL.md
plugins/expo/skills/expo-ui/SKILL.md

Metadata

Files
0
Version
a9e5bd3
Hash
8f8c08df
Indexed
2026-07-24 22:02

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-11-03 15:07
浙ICP备14020137号-1