• Projects
  • Service
  • About
  • branding.bz
  • Podcast
  • Tips
  • FAQ
  • Recruit
  • Download
  • Contact
  • branding.bz(ブランド構築SaaS)
  • DESIGN NOW(デザインメディア)
  • X
  • LinkedIn
  • Spotify
  • Facebook

213-0011 神奈川県川崎市高津区久本3-6-7-303

© 2026 ID INC. All rights reserved

claude-skills/スキル
SKILLOfficialdevelopment

expo-router

プラグイン
expo
ライセンス
MIT
ソース
GitHub で見る ↗
説明

**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でアプリの画面遷移を設定するとき
  • ファイル構成に基づくルーティングを実装するとき
  • 動的ルートやルートグループを使いこなしたいとき
  • モーダルやタブメニューなどの画面要素を構築するとき
  • ヘッダーやツールバーのUI設定を行うとき
本文(日本語訳)

Expo Router ナビゲーション

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)
  • ナビゲーションを移動・再構成する際は、古いルート ファイルを必ず削除する
  • ファイル名に特殊文字を使用しない
  • tsconfig.json でパス エイリアス(ショートカット名)を設定し、相対的なパス指定より優先させる

ルート

詳細なルート規約については ./references/route-structure.md をご覧ください。

  • ルートは app ディレクトリに配置する
  • コンポーネント、型定義、ユーティリティを app ディレクトリに混在させない(避けるべきパターン)
  • アプリ常に "/" にマッチするルートを持つようにする(グループ ルート内でも可)

ライブラリの選択

  • Color(expo-router 由来)を使用してネイティブなセマンティック カラー(意味に基づく色)を指定する。生の PlatformColor は使わない(型安全で、ライト/ダーク モードに自動対応)。完全な色パレット パターンについては expo-native-ui を参照
  • SDK 56 以上では、@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 ファイルを使用してスタック(ナビゲーション階層)を定義する(必須)
  • 'expo-router/stack' の Stack を使用してネイティブ ナビゲーション スタックを構築する

ページ タイトル

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 フローに従ってください。

原文(English)を表示

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. 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 による自動翻訳です。