• 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 スキルを、モーション(動き)とジェスチャー(タッチ操作)については expo-animation を使用してください。

リファレンス

必要に応じてこれらのリソースを参照してください:

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 ディレクトリに同じ場所に配置しないでください(避けるべきパターンです)
  • アプリは常に "/" に一致するルートを持つようにしてください。グループルート内に配置してもかまいません

ライブラリの選定基準

  • expo-router の Color を使用してください。生の PlatformColor ではなく型安全で、ライト・ダークモードに自動対応します。完全なカラーパレットパターンについては expo-native-ui を参照してください
  • SDK 56 以降では、@react-navigation/* から直接インポートしないでください。代わりに expo-router/react-navigation を使用してください(@react-navigation/native、/core、/elements、/routers をカバーしています)

動作

  • 画面に検索バーを追加する場合は、@react-navigation/* の代わりに Stack.SearchBar を優先してください

ナビゲーション

Link(リンク)

'expo-router' の <Link href="/path" /> を使用してルート間を遷移します。

import { Link } from 'expo-router';

// 基本的なリンク
<Link href="/path" />

// カスタムコンポーネントをラップする
<Link href="/path" asChild>
  <Pressable>...</Pressable>
</Link>

できるだけ <Link.Preview> を含めて iOS の慣例に従うようにしてください。ナビゲーション体験を向上させるために、コンテキストメニュー(長押しで表示するメニュー)とプレビューを頻繁に追加してください。

Stack(スタック)

  • _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>

リンクプレビューはコンテキストメニューと一緒に使用できます。

Modal(モーダル)

画面をモーダル(ユーザーの操作を強制する対話型ウィンドウ)として表示します:

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

カスタムモーダルコンポーネントを作成するより、この方法を優先してください。

Sheet(シート)

画面を動的なフォームシート(下からスライドアップするパネル)として表示します:

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

headerLargeTitleEnabled は SDK 56 以降のオプション名です。古い SDK は headerLargeTitle を使用しますが、これは公式に推奨されなくなっています。

フィードバックの送信

このスキルでエラーや誤った情報、古い情報に出会った場合は、報告して 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, 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 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 による自動翻訳です。