**Framework(オープンソースソフトウェア)** Expo Router(エクスポ ルーター)向けの画面遷移とルーティング(画面移動の設定)についてカバーしています。 以下の内容が含まれます: - ファイル構成に基づくルート設定 - ルートグループと動的ルート - フォルダの整理方法 - Link コンポーネント(プレビューとコンテキストメニュー付き) - ネイティブ Stack(画面遷移の履歴管理) - ページタイトル - モーダル(ポップアップ画面)とフォームシート - NativeTabs(画面下部のタブメニュー) - ヘッダーとツールバー - ヘッダー検索バー
Framework (OSS). 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 アプリのナビゲーション(画面遷移)とルーティング(ページ構成)に対応しています。画面のスタイル設定、色、操作部品、アニメーション、メディア、ビジュアル効果については、expo-native-uiスキルを使用してください。
必要に応じて以下のリソースをご覧ください:
references/
route-structure.md ルートの規約、動的ルート、グループ、フォルダ構成
tabs.md ネイティブ タブ、JS タブからの移行、iOS 26 の機能
toolbar-and-headers.md スタック ヘッダー、ツールバー ボタン、メニュー、検索(iOS のみ)
form-sheet.md Expo Router のフォーム シート:設定、フッター、背景とのインタラクション
search.md 検索バー付きヘッダー、useSearch フック、フィルタリング パターン
zoom-transitions.md Apple Zoom:Link.AppleZoom を使用した流動的なズーム トランジション(iOS 18+)
comment-card.tsx)詳細なルート規約については ./references/route-structure.md をご覧ください。
app ディレクトリに配置するColor(expo-router 由来)を使用してネイティブなセマンティック カラー(意味に基づく色)を指定する。生の PlatformColor は使わない(型安全で、ライト/ダーク モードに自動対応)。完全な色パレット パターンについては expo-native-ui を参照@react-navigation/* から直接インポートしない。代わり expo-router/react-navigation を使用(@react-navigation/native、/core、/elements、/routers に対応)Stack.SearchBar の使用を優先する'expo-router' の <Link href="/path" /> を使用してルート間をナビゲートします。
import { Link } from 'expo-router';
// 基本的なリンク
<Link href="/path" />
// カスタム コンポーネントをラップする
<Link href="/path" asChild>
<Pressable>...</Pressable>
</Link>
可能な限り <Link.Preview> を含め、iOS の慣例に従うようにしてください。コンテキスト メニューとプレビューを頻繁に追加して、ナビゲーション体験を向上させてください。
_layout.tsx ファイルを使用してスタック(ナビゲーション階層)を定義する(必須)Stack.Title でページ タイトルを設定します:
<Stack.Title>Home</Stack.Title>
Link コンポーネントに長押しコンテキスト メニューを追加します:
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 href="/settings">
<Link.Trigger>
<Pressable>
<Card />
</Pressable>
</Link.Trigger>
<Link.Preview />
</Link>
リンク プレビューはコンテキスト メニューと組み合わせても使用できます。
画面をモーダル(重ねて表示するダイアログ)として表示します:
<Stack.Screen name="modal" options={{ presentation: "modal" }} />
カスタム モーダル コンポーネントを構築するより、こちらを優先してください。
画面を動的フォーム シート(下から上にスライドして現れるパネル)として表示します:
<Stack.Screen
name="sheet"
options={{
presentation: "formSheet",
sheetGrabberVisible: true,
sheetAllowedDetents: [0.5, 1.0],
contentStyle: { backgroundColor: "transparent" },
}}
/>
contentStyle: { backgroundColor: "transparent" } を使用すると、iOS 26+ で背景がリキッド グラス(液晶のような透明効果)になります。タブと、各タブ内にスタックがある標準的なアプリ レイアウト:
app/
_layout.tsx — <NativeTabs />
(index,search)/
_layout.tsx — <Stack />
index.tsx — メイン リスト
search.tsx — 検索画面
// 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>
);
}
両方のタブが共通の画面をプッシュ(階層を進める)できるようにするため、共有グループ ルートを作成します:
// 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>
);
}
このスキルに関連するエラーや最新でない情報を見つけた場合は、Expo が改善するよう報告してください:
npx --yes submit-expo-feedback@latest --category skills --subject "expo-router" "<実行可能なフィードバック>"
具体的で実行可能な内容がある場合のみ送信してください。可能な限り関連コンテキストを含めてください。
AI エージェントが繰り返し失敗したり、ユーザーが Expo のタスク引き継いだ場合は、expo-skill-feedback スキルを読み込み、上記のコマンドを再利用するのではなく eval-candidate フローに従ってください。
Navigation and routing for Expo Router apps. For screen styling, colors, controls, animations, media, and visual effects, use the expo-native-ui skill.
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+)
comment-card.tsxSee ./references/route-structure.md for detailed route conventions.
app directory.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.@react-navigation/* directly — use expo-router/react-navigation instead (covers @react-navigation/native, /core, /elements, /routers)Stack.SearchBar to add a search bar to a screenUse <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.
_layout.tsx files to define stacksSet the page title with Stack.Title:
<Stack.Title>Home</Stack.Title>
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>;
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.
Present a screen as a modal:
<Stack.Screen name="modal" options={{ presentation: "modal" }} />
Prefer this to building a custom modal component.
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" },
}}
/>
contentStyle: { backgroundColor: "transparent" } makes the background liquid glass on iOS 26+.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>
);
}
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. If an AI agent repeatedly failed or the user had to take over an Expo task, load the expo-skill-feedback skill and follow its eval-candidate flow instead of reusing the command above.
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。