
フロントエンド開発の歴史において、Next.js 13で導入された「App Router」は、単なるマイナーアップデートではなく、Reactアプリケーションの作り方を根底から変える「巨大なパラダイムシフト」でした。
これまでの pages ディレクトリを使用する方式(Pages Router)に慣れていた開発者にとって、当初は「難解だ」「冗長になった」という声もありましたが、現在ではその圧倒的なパフォーマンスと開発体験の良さが広く認められています。
この記事では、App Routerの中核をなす技術要素から、現場で迷いやすいポイントまでを徹底的に深掘りしていきます。
1. App Router とは何か?(Pages Router との最大の違い)
App Routerは、Reactの最新機能である React Server Components (RSC) を最大限に活用するために設計された、新しいルーティングシステムです。
根本的な考え方の違い
- Pages Router: クライアントサイドでのルーティングが主体。データ取得(getServerSidePropsなど)はページのトップレベルでのみ可能。
- App Router: サーバーサイドでのルーティングが主体。コンポーネント単位で「これはサーバーで動かす(Server Components)」「これはクライアントで動かす(Client Components)」を細かく制御。
これにより、ブラウザに送信されるJavaScriptの量を劇的に減らし、ページの読み込み速度を飛躍的に向上させることが可能になりました。
2. Server Components vs Client Components の使い分け
App Routerを理解する上で、最も重要なのがこの2つの使い分けです。App Router内のコンポーネントは、デフォルトではすべて Server Components として扱われます。
Server Components (SC) の特徴
- サーバー上でのみ実行: 重いライブラリをクライアントに送る必要がない。
- 秘密情報の保持: DBとの直接通信やAPIキーの隠匿が容易。
- パフォーマンス: クライアントサイドのJSが増えないため、LCP(読み込み速度)に有利。
- 制限:
useStateやuseEffect、ブラウザ専用API(windowなど)は使えない。
Client Components (CC) の特徴
- ユーザーとの対話: ボタンクリック、フォーム入力、モーダルの開閉など。
- Hooksの利用:
useState,useContextなどが使える。 - 宣言: ファイルの先頭に
"use client"と記述することで定義。
黄金のルール
「可能な限り Server Components を使い、ユーザーのインタラクションが必要な最小単位だけを Client Components に切り出す」 これが、爆速のNext.jsアプリを作るための鉄則です。
3. ファイルシステムベースの新しいルーティング
App Routerでは、ディレクトリ構造がそのままURLの構造を反映します。しかし、Pages Routerと異なり、page.js (または page.tsx) という名前のファイルだけが公開ページとして認識されます。
主要な特殊ファイル
layout.tsx: 複数のページで共有されるレイアウト(状態を維持し、再レンダリングを防ぐ)。page.tsx: ページのメインコンテンツ。loading.tsx: データの読み込み中に自動で表示されるローディングUI(Suspenseを自動適用)。error.tsx: エラーが発生した際に表示されるフォールバックUI。not-found.tsx: 404エラーを表示。
このディレクトリ構造のおかげで、コンポーネントやスタイルシート、テストファイルをページファイルと同じフォルダ内に整理(コロケーション)できるようになり、プロジェクトの管理が非常に楽になりました。
4. 進化したデータフェッチ(Data Fetching)
App Routerでのデータ取得は、非常にシンプルになりました。
非同期コンポーネント
Server Componentsは async/await を直接サポートしています。
// app/blog/page.tsx
async function getPosts() {
const res = await fetch('https://api.example.com/posts');
// 標準の fetch を拡張しており、キャッシュの制御が容易
return res.json();
}
export default async function BlogPage() {
const posts = await getPosts();
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
キャッシュの制御
fetch オプションによって、ISR(Incremental Static Regeneration)やSSG(Static Site Generation)の挙動を簡単に切り替えられます。
force-cache(デフォルト): SSGのようにキャッシュ。revalidate: 60: 60秒ごとにキャッシュを更新(ISR相当)。no-store: 常に最新を取得(SSR相当)。
5. App Router 移行へのアドバイス
「既存の Pages Router プロジェクトを移行すべきか?」と悩んでいる方も多いでしょう。
- 新規プロジェクト: 迷わず App Router を選択してください。エコシステムも整い、メリットが上回ります。
- 既存の大規模プロジェクト: 段階的な移行が可能です。
appディレクトリとpagesディレクトリは共存できるため、新しい機能から少しずつ App Router へ移していくのが現実的です。
まとめ:Next.js の真価を引き出すために
Next.js App Routerは、一見複雑に見えるかもしれませんが、その本質は「Webをより高速に、よりシンプルにする」ことにあります。
- Server Components をデフォルトとし、JSを減らす。
- Layout を使って効率的なUI設計をする。
- async/await で直感的なデータフェッチを行う。
これらを意識するだけで、あなたの開発するWebサイトのパフォーマンスは格段に向上します。これからのフロントエンド開発において、App Routerの習得は避けて通れない道です。ぜひ、実際に手を動かして、その新しさを体感してみてください。
次回の記事では、App Routerでの「フォーム送信とServer Actions」について詳しく解説します!