# Expo RouterによるReact Nativeファイルベースナビゲーション完全ガイド
> Expo Routerを使ったReact Nativeのファイルベースルーティングを徹底解説。レイアウト、ダイナミックルート、型安全なナビゲーション、タブ、モーダル、ミドルウェアまで、2026年最新のパターンを網羅します。
- Published: 2026-04-18
- Updated: 2026-04-18
- Author: SharpSkill
- Tags: react-native, expo, expo-router, navigation, mobile-development, tutorial
- Reading time: 9 min
---
Expo Routerは、React Nativeアプリケーションにおけるナビゲーション管理の方法を根本的に変革するライブラリです。Next.jsで普及したファイルベースルーティングの仕組みをモバイル開発に持ち込み、`app`ディレクトリ内にファイルを作成するだけで画面遷移が定義されます。Expo SDK 55とExpo Router v6の組み合わせにより、React Navigationの手動設定は不要となり、Android、iOS、Webのすべてのプラットフォームで統一的なナビゲーション体験を提供できます。ディープリンク、型安全なルーティング、サーバーミドルウェアといった機能を標準で備えており、クロスプラットフォーム開発の生産性を大幅に向上させます。
> **クイックセットアップ**
>
> 新規Expoプロジェクトでは、Expo Routerがデフォルトで組み込まれています。`npx create-expo-app@latest --template default@sdk-55`を実行すると、ファイルベースルーティングが事前設定されたプロジェクトが生成されます。既存プロジェクトの場合は、`expo-router`パッケージをインストールし、アプリケーションのエントリポイントを更新するだけで導入できます。
## Expo Routerにおけるファイルベースルーティングの仕組み
`app`ディレクトリ内に配置されたすべてのファイルが、自動的にルートとして認識されます。ファイルパスがそのままURLパスに対応するため、集中型のルーティング設定ファイルは一切不要です。例えば、`app/settings.tsx`を作成すると`/settings`というルートが生成され、`app/profile/edit.tsx`は`/profile/edit`に対応します。
この規約ベースのアプローチは、従来のReact Navigationによる手動設定と比較して、以下の3つの大きな利点をもたらします。
- **設定不要**: ファイルを作成した時点でルートが有効になる
- **自動ディープリンク**: すべての画面にURLが付与され、共有やテストが容易になる
- **型付きナビゲーション**: TypeScriptがコンパイル時に存在するルートを認識する
```typescript
// app/index.tsx
import { View, Text, StyleSheet } from 'react-native'
import { Link } from 'expo-router'
export default function HomeScreen() {
return (
Welcome
{/* Link maps directly to file path */}
Open Settings
Edit Profile
)
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', padding: 24 },
title: { fontSize: 28, fontWeight: 'bold', marginBottom: 16 },
link: { fontSize: 16, color: '#61DAFB', marginTop: 12 },
})
```
`Link`コンポーネントは、すべてのプラットフォームでナビゲーションを処理します。Webでは適切な`href`属性を持つアンカータグが生成され、SEOに対応した構造が得られます。ネイティブプラットフォームでは、スタック型のナビゲーション遷移がトリガーされます。
## プロジェクト構成とレイアウトファイル
Expo Routerでは、`_layout.tsx`ファイルを使用してナビゲーションコンテナを定義します。各ディレクトリに独自のレイアウトファイルを配置でき、ネストされたナビゲーション階層の構築が可能です。ルートレイアウトはアプリケーション全体を包括し、ネストされたレイアウトは特定のセクションを制御します。
典型的なプロジェクト構成は以下のとおりです。
```text
app/
_layout.tsx # Root layout (Stack or custom)
index.tsx # Home screen (/)
(tabs)/ # Tab group (parentheses = route group)
_layout.tsx # Tab navigator
home.tsx # /home tab
search.tsx # /search tab
profile.tsx # /profile tab
settings/
_layout.tsx # Settings stack layout
index.tsx # /settings
notifications.tsx # /settings/notifications
privacy.tsx # /settings/privacy
```
ルートグループ(括弧で囲まれたディレクトリ)は、URLに影響を与えずにファイルを論理的に整理するための仕組みです。上記の`(tabs)`ディレクトリはタブナビゲータを構成しますが、URLは`/tabs/home`ではなく`/home`、`/search`、`/profile`のままです。
```typescript
// app/_layout.tsx
import { Stack } from 'expo-router'
export default function RootLayout() {
return (
)
}
```
ルートレイアウトは、フォントの読み込み、プロバイダーの設定、グローバル設定の初期化を行う場所でもあります。従来の`App.tsx`に代わるアプリケーションのエントリポイントとして機能します。
## Expo Routerによるタブナビゲーションの構築
タブナビゲーションを実装するには、ルートグループ内に`_layout.tsx`ファイルを配置します。Expo Router v6では、プラットフォーム固有のネイティブ体験を提供する`NativeTabs`が導入されていますが、標準の`Tabs`コンポーネントでほとんどのユースケースに対応できます。
```typescript
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router'
import { Ionicons } from '@expo/vector-icons'
export default function TabLayout() {
return (
(
),
}}
/>
(
),
}}
/>
(
),
}}
/>
)
}
```
各タブ画面のファイルは、標準的なReactコンポーネントをエクスポートするだけです。タブバーのアイコン、ラベル、バッジなどの設定は、レイアウトファイルの`options`プロップで制御します。
## ダイナミックルートとルートパラメータ
動的セグメントは、ファイル名に角括弧を使用して定義します。`[id].tsx`という名前のファイルは単一のセグメントに対応し、`[...slug].tsx`はパス内の残りのすべてのセグメントをキャプチャします。
```typescript
// app/product/[id].tsx
import { View, Text, StyleSheet } from 'react-native'
import { useLocalSearchParams, Stack } from 'expo-router'
export default function ProductScreen() {
// Extract the dynamic parameter from the URL
const { id } = useLocalSearchParams<{ id: string }>()
return (
Product Details
ID: {id}
)
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 24 },
heading: { fontSize: 24, fontWeight: 'bold', marginBottom: 8 },
id: { fontSize: 16, color: '#888' },
})
```
`/product/42`にアクセスすると、この画面が表示され、`id`変数に`"42"`が設定されます。`useLocalSearchParams`フックは、ルートパラメータへの型付きアクセスを提供します。
キャッチオールルートでは、`[...slug].tsx`がパスセグメント全体をキャプチャします。
```typescript
// app/docs/[...slug].tsx
import { useLocalSearchParams } from 'expo-router'
export default function DocsScreen() {
// /docs/getting-started/installation → slug = ['getting-started', 'installation']
const { slug } = useLocalSearchParams<{ slug: string[] }>()
return
}
```
## 型安全なルーティング(Typed Routes)
Expo Routerは、Typed Routes機能を有効にすると、ルートの型定義を自動生成します。この検証機能により、リンク切れをランタイムではなくコンパイル時に検出できます。
`app.json`で以下のように設定します。
```json
{
"expo": {
"experiments": {
"typedRoutes": true
}
}
}
```
この設定を有効にすると、`Link`コンポーネントの`href`プロップや`router.push()`の引数には、実際に存在するルートに対応する文字列のみが許容されます。
```typescript
// app/checkout.tsx
import { router } from 'expo-router'
function handleCheckout(cartId: string) {
// TypeScript validates this route exists
router.push(`/product/${cartId}`)
// This would cause a compile error if /nonexistent doesn't exist
// router.push('/nonexistent')
}
```
Typed Routesは`useLocalSearchParams`と組み合わせることで特に効果を発揮します。自動生成された型定義により、ルート定義内のパラメータ名とコンシューマコンポーネントで使用されるパラメータ名の一致が保証されます。特定の画面に遷移した際にのみ発見されるような微妙なバグを未然に防止できます。
## モーダル画面とプレゼンテーション設定
Expo Routerにおけるモーダルは、レイアウトで`presentation: 'modal'`を指定した通常の画面です。ファイルベースルーティングの規約に忠実に、モーダルも単なるルートの1つとして扱われます。
```typescript
// app/_layout.tsx
import { Stack } from 'expo-router'
export default function RootLayout() {
return (
{/* Modal screen slides up from the bottom */}
)
}
```
```typescript
// app/create-post.tsx
import { View, TextInput, Button, StyleSheet } from 'react-native'
import { router } from 'expo-router'
import { useState } from 'react'
export default function CreatePostModal() {
const [title, setTitle] = useState('')
const handleSubmit = () => {
// Submit logic here
router.back() // Dismiss the modal
}
return (
)
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 24 },
input: {
borderWidth: 1,
borderColor: '#333',
borderRadius: 8,
padding: 12,
fontSize: 16,
marginBottom: 16,
},
})
```
`/create-post`にナビゲートすると、モーダルプレゼンテーションが起動します。`router.back()`を呼び出すことでモーダルが閉じられ、ナビゲーションスタックの前の画面に戻ります。
## プログラムによるナビゲーションとRouter API
`Link`コンポーネント以外に、Expo Routerは`router`オブジェクトを通じた命令的なAPIを提供します。このAPIにより、ユーザーの直接的な操作ではなく、ビジネスロジックに基づいたナビゲーション制御が可能になります。
```typescript
import { router } from 'expo-router'
// Push a new screen onto the stack
router.push('/profile/settings')
// Replace the current screen (no back button)
router.replace('/login')
// Go back to the previous screen
router.back()
// Navigate with parameters
router.push({
pathname: '/product/[id]',
params: { id: '42', source: 'recommendations' },
})
// Check if going back is possible
import { useRouter } from 'expo-router'
function BackButton() {
const router = useRouter()
return router.canGoBack() ? (