Next.js App Routerのフォルダ構造: ベストプラクティスとエンタープライズアーキテクチャ (2026)

Table of Contents
Modern Next.js Architecture Series
Reactアプリケーションがスケールするにつれて、フォルダ構造は個人的な美学の問題から、基礎的なアーキテクチャの決定へと移行します。Next.js App Routerの導入により、古いメンタルモデルは崩壊しました。私たちは、レガシーなpages/ディレクトリ(ルーティングとUIコンポーネントの両方のゴミ捨て場になりがちでした)から、app/内の意見が明確で規約に基づいたルーティングシステムへと移行しました。
しかし、App Routerの柔軟性、特にコロケーション(colocation)のサポートは、諸刃の剣です。明確な構造的ガードレールがなければ、app/ディレクトリはすぐに何百もの混在ファイル、循環依存、サーバー/クライアント境界の漏洩で膨れ上がってしまいます。
このガイドでは、Next.js App Routerアプリケーション向けに本番環境でテストされたフォルダ構造を、基本的なコロケーションからエンタープライズアプリケーション向けの**Feature-Sliced Design (FSD)**まで、詳しく解説します。
App Routerのパラダイムシフト:ルーティング vs ドメインロジック
App Routerは、app/ディレクトリをHTTPルーターおよびページコンポジターとして厳密に扱います。公開アクセス可能なのは、特別な規約ファイルのみです。
page.tsx: URL経由でアクセス可能な、ルート固有のUI。layout.tsx: 子要素をラップし、ナビゲーション間で状態を保持する共有UI。loading.tsx: React Suspenseによって提供されるストリーミングフォールバック。error.tsx: ルートサブツリー内のランタイムエラーを捕捉するクライアントサイドのエラー境界。not-found.tsx:404状態のUI。route.ts: サーバーサイドAPIエンドポイント(GET、POST、PUT、DELETE)。
ルートフォルダ内のその他すべてのものは、技術的にはコロケーション可能です。
app/
└── dashboard/
├── page.tsx
├── layout.tsx
├── DashboardGraph.tsx # Colocated component
├── dashboard.module.css # Colocated styling
└── dashboard.test.tsx # Colocated unit test
純粋なコロケーションの落とし穴
app/内にすべてをコロケーションする方法はMVP(Minimum Viable Product)には適していますが、中規模から大規模のプロジェクトでは破綻します。
- 再利用性のボトルネック: 別のルート(例:
app/reports/page.tsx)がDashboardGraphを必要とする場合、それはどこに置かれるべきでしょうか?上に移動すると、予測不能なインポートパスが生成されます。 - 汚染されたファイルツリー: 30のルートと200のコロケーションされたファイルを持つ
app/フォルダでは、オンコールインシデント中にルートを見つけるのが非常に困難になります。 - 曖昧な境界: 開発者が誤って
'use client'を親ラッパーに追加し、Server Componentのストリーミングを最適化できなくしてしまいます。
3つのアーキテクチャモデル:あなたの規模に合うのはどれ?
| Model | Best For | Strengths | Trade-offs |
|---|---|---|---|
| 1. Colocated App | MVPs & 小規模サイト (<10ルート) | 高速なセットアップ、メンタルオーバーヘッドなし | ルート間でコードを共有する際にスパゲッティインポートが発生 |
| 2. Layered Flat | スタートアップ & 中規模アプリ (10-40ルート) | 標準的なReactチームには馴染み深い | 巨大なcomponents/およびhooks/フォルダがジャンクドロワーになる |
| 3. Feature-Sliced (FSD) | エンタープライズ & 大規模 (40+ルート、複数チーム) | 厳格な単方向境界、疎結合な機能 | ジュニア開発者にとっては初期学習曲線がある |
ルートグループ vs プライベートフォルダ
Next.jsは、ルーティングを内部ロジックからきれいに分離するための2つの重要なフォルダ規約を提供します。
1. ルートグループ (folder)
フォルダ名を括弧で囲むと、公開URLを変更せずにルートを論理的に整理できます。
app/
├── (marketing)/
│ ├── layout.tsx # Marketing layout (Navigation bar + Footer)
│ ├── page.tsx # Served at: /
│ └── pricing/
│ └── page.tsx # Served at: /pricing
└── (dashboard)/
├── layout.tsx # Dashboard layout (Sidebar + Account switcher)
├── settings/
│ └── page.tsx # Served at: /settings
└── analytics/
└── page.tsx # Served at: /analytics
ルートグループを使用する理由
- 複数のルートレイアウトを作成する(例:公開ランディングページ vs 保護された認証済みダッシュボード)。
- SEOに影響するURLを変更せずに、チームの所有権ごとにルートをグループ化する。
- セクションごとにローディング状態とエラー状態を分離する。
2. プライベートフォルダ _folder
フォルダ名の前にアンダースコアを付けると、Next.jsにそのフォルダをルーティングから完全に除外するように指示します。
app/
├── (dashboard)/
│ └── analytics/
│ ├── _components/ # OPTED OUT of routing (/analytics/_components is 404)
│ │ ├── Chart.tsx
│ │ └── MetricCard.tsx
│ ├── _lib/
│ │ └── calculations.ts
│ └── page.tsx # Served at: /analytics
_componentsまたは_libは、単一のルートに厳密にプライベートであり、他の場所で再利用されることのないコードをコロケーションしたい場合に使用します。
推奨されるエンタープライズアーキテクチャ:Feature-Sliced Design
ミッションクリティカルな本番アプリケーションでは、Next.jsのルーティングをドメインビジネスロジックから分離するために、4層アーキテクチャを使用します。
src/
├── app/ # Layer 1: Next.js routing, layouts, and page composition
├── features/ # Layer 2: Business actions and user workflows
├── entities/ # Layer 3: Domain data models and business entities
└── shared/ # Layer 4: Foundation (UI primitives, API clients, helpers)
依存関係グラフの可視化
Feature-Sliced Designで最も重要なルールは、単方向の依存関係です。コードは、厳密に下位のレイヤーからのみインポートできます。
各レイヤーの動作
1. app/レイヤー:純粋なコンポジション
app/ディレクトリにはビジネスロジックが一切含まれていません。以下のことのみを行います。
- ルートとネストされたレイアウトを宣言する。
- Server Components内でデータをフェッチする。
- 機能とエンティティをページテンプレートに構成する。
// src/app/(dashboard)/analytics/page.tsx
import { Suspense } from 'react';
import { AnalyticsMetrics } from '@/features/usage-metrics';
import { getCurrentUser } from '@/entities/user';
import { SkeletonLoader } from '@/shared/ui';
export default async function AnalyticsPage() {
const user = await getCurrentUser();
return (
<main className="container mx-auto p-6 space-y-6">
<header>
<h1 className="text-3xl font-bold tracking-tight">Analytics</h1>
<p className="text-muted-foreground">Welcome back, {user.name}</p>
</header>
<Suspense fallback={<SkeletonLoader count={4} />}>
<AnalyticsMetrics organizationId={user.orgId} />
</Suspense>
</main>
);
}
2. features/レイヤー:ユーザーワークフロー
機能には、測定可能なビジネス価値を提供するインタラクティブなユーザーフローが含まれます(例: auth-flow、checkout、team-invitation)。
src/features/auth-flow/
├── ui/ # React client/server components
│ ├── LoginForm.tsx
│ └── SocialButtons.tsx
├── api/ # Colocated Server Actions
│ └── authenticate.ts
├── model/ # Local state, validation schemas
│ └── schema.ts
└── index.ts # STRICT Public API export
内部をプライベートに保つために、常にindex.tsを介してエクスポートしてください。
// src/features/auth-flow/index.ts
export { LoginForm } from './ui/LoginForm';
export { authenticateWithOAuth } from './api/authenticate';
3. entities/レイヤー:コアビジネスエンティティ
エンティティは、ドメイン内の現実世界の概念を表します(例: User、Workspace、Invoice)。これらには以下が含まれます。
- データベースクエリ関数またはAPIエンドポイント。
- TypeScriptインターフェースとZodスキーマ。
- 特定のエンティティに結びついたUI要素(例:
<UserAvatar />、<PlanBadge />)。
4. shared/レイヤー:再利用可能な基盤
shared/ディレクトリには、理論的には内部npmパッケージとして公開できる、ドメインに依存しないコードが格納されます。
shared/ui:Button、Modal、Input、Dropdownなどのプリミティブ(多くの場合、Shadcn / Radixラッパー)。shared/lib: 日付フォーマッター、数学ユーティリティ、ネットワーククライアント。shared/config: 環境変数検証(Zod)とサイトメタデータ。
フォルダツリーにおけるサーバーコンポーネントとクライアントコンポーネントの境界
Next.jsアプリの速度低下の最も一般的な原因の1つは、「クライアントコンポーネント汚染」です。これは、ページの先頭に'use client'を追加すると、すべての子コンポーネントがクライアントJavaScriptバンドルで実行されてしまう現象です。
これを避けるには、フォルダ構造で**「リーフのみのクライアントコンポーネント」**ルールに従ってください。
app/(dashboard)/dashboard/page.tsx # [Server Component] Fetches data
├── DashboardSummary.tsx # [Server Component] Pure HTML rendering
└── _components/
└── InteractiveFilter.tsx # ['use client'] ONLY interactive button/state
親ページをServer Componentのままにし、Client Componentをリーフの位置にインポートすることで、クライアントJavaScriptバンドルを最小限に抑え、Next.jsのハイドレーションミスマッチエラーを解消できます。
本番環境対応テンプレート(コピー&ペースト)
以下は、エンタープライズNext.js App Routerアプリケーション向けに実証済みのディレクトリ構造です。
my-app/
├── public/
│ └── static/
├── src/
│ ├── app/
│ │ ├── (auth)/
│ │ │ ├── login/page.tsx
│ │ │ ├── signup/page.tsx
│ │ │ └── layout.tsx
│ │ ├── (dashboard)/
│ │ │ ├── layout.tsx
│ │ │ ├── overview/page.tsx
│ │ │ └── settings/
│ │ │ ├── page.tsx
│ │ │ └── _components/
│ │ ├── api/
│ │ │ └── webhooks/stripe/route.ts
│ │ ├── favicon.ico
│ │ ├── global-error.tsx
│ │ ├── layout.tsx
│ │ └── not-found.tsx
│ │
│ ├── features/
│ │ ├── auth/
│ │ │ ├── ui/
│ │ │ ├── api/
│ │ │ └── index.ts
│ │ └── billing/
│ │ ├── ui/
│ │ ├── api/
│ │ └── index.ts
│ │
│ ├── entities/
│ │ ├── user/
│ │ │ ├── ui/UserAvatar.tsx
│ │ │ ├── model/types.ts
│ │ │ └── index.ts
│ │ └── organization/
│ │
│ └── shared/
│ ├── ui/ # Reusable design system components
│ ├── lib/ # Utilities (cn, formatters)
│ └── hooks/ # Domain-agnostic React hooks
│
├── middleware.ts # Edge routing & auth guards
├── next.config.mjs
└── tsconfig.json
知識を試す:App Routerアーキテクチャ
こちらもおすすめ
- React Testing Library user-event v14: ベストプラクティスとfireEventへの移行 (2026)
- RustとWebAssemblyでReactを強化する:包括的なガイド
- フロントエンド開発者のためのRust:実践的な移行ガイド
- JavaScriptにおけるIntersection Observer vs getBoundingClientRect:パフォーマンスの詳細分析
よくある質問
(folder)は、URLパスにセグメントを追加せずにルートをグループ化し、複数のルートレイアウトを可能にするルートグループです。_folderは、ルーティングシステムから完全に除外され、子ファイルが公開エンドポイントになるのを防ぐプライベートフォルダです。
汎用的でドメインに依存しないUIコンポーネント(ボタン、モーダル、入力など)は、src/shared/ui/またはsrc/components/ui/に配置します。ドメイン固有のコンポーネントは、src/features/[feature-name]/ui/またはルート内のプライベートな_componentsフォルダに配置すべきです。
はい、できます。Feature-Sliced Designでは、'use server'アクションファイルをfeatures/[feature-name]/api/actions.ts内にコロケーションすることをお勧めします。これにより、ミューテーションをトリガーするUIフォームの近くに保ちながら、クリーンな境界を維持できます。
並列ルートは@name規約を使用して、同じレイアウト内で複数のページを同時にレンダリングします(例: @modal)。インターセプトルートは(.)routeまたは(..)routeを使用して、URLコンテキストを変更せずに現在のビュー内の別のセグメントからルートをロードします。これはフォトギャラリーやログインモーダルに最適です。
Next.jsのapp/は、ルーティング、ストリーミング、HTTPメカニズムに最適化されています。重いドメインロジック、複雑なステートマシン、ビジネスワークフローを直接app/に配置すると、ファイル間の結合が非常に強くなり、単体テストが困難になり、意図しない循環依存が発生します。
関連する詳細解説
本番環境のNext.jsアーキテクチャをさらにレベルアップさせるために、これらの補完的なガイドもご覧ください。
- Next.js Hydration Error: 「Text Content Mismatch」と418を修正する:クライアントの状態とサードパーティの拡張機能によって引き起こされるSSRの不一致を防ぎます。
- Next.js App Routerのキャッシュと再検証戦略:本番環境におけるNext.jsの4層キャッシュをマスターします。
- React 19 Server Actionsと楽観的更新:クライアントサイドの遅延なしに超高速フォームを構築します。
- PrismaとPostgreSQLを使用したNext.js App Router:Server Components向けの直接データベース統合パターン。
- Next.jsのメタデータ、SEO、Open Graphガイド:動的なソーシャルシェアリングプレビューとJSON-LDスキーマを生成します。
Free In-Browser Developer Tools
Clean AI CLI logs, build cron expressions, decode JWTs, and calculate chmod permissions offline.
Related Articles

Next.jsにおけるsuppressHydrationWarning: 安全な利用法とデバッグの完全ガイド
Next.jsのsuppressHydrationWarningについて、安全な利用法とデバッグ方法を実証済みの本番環境での例を交えて網羅的に解説する包括的なガイドです。
Read more
Next.js15におけるServerActionsとRouteHandlers:詳細なアーキテクチャ比較
Next.js15でServerActionsとRouteHandlersのどちらを選択すべきかを習得し、プログレッシブエンハンスメント、キャッシング動作、RPCプロトコル、セキュリティ境界について深く掘り下げます。
Read more
ReactのState管理2026: Reduxの先へ
React19のactions、TanStack Queryのサーバーstate、Zustand、Jotai、Signalsを比較し、2026年のReactにおけるstate管理を包括的に解説します。
Read more