【2026年版】Next.js App Router完全ガイド|Server Components・データフェッチ・デプロイまで実践解説

Next.js 13以降で導入されたApp Routerは、Webアプリケーション開発の概念を根本から変えました。2026年現在、多くの企業でApp Routerへの移行が完了しており、新規プロジェクトはApp Routerが標準となっています。

App RouterとPages Routerの違い

  • Server Componentsがデフォルト:サーバーサイドでレンダリングされ、バンドルサイズを削減
  • ファイルベースの規約:page.tsx、layout.tsx、loading.tsx など特定のファイル名で機能を実現
  • ネストされたレイアウト:階層的なレイアウト定義が可能
  • Streaming:コンポーネント単位での段階的レンダリング

プロジェクト構成

my-app/
├── app/
│   ├── layout.tsx          # ルートレイアウト
│   ├── page.tsx            # トップページ
│   ├── loading.tsx         # ローディングUI
│   ├── error.tsx           # エラーUI
│   ├── not-found.tsx       # 404ページ
│   ├── globals.css
│   └── blog/
│       ├── layout.tsx      # ブログセクションのレイアウト
│       ├── page.tsx        # ブログ一覧
│       └── [slug]/
│           └── page.tsx    # 記事詳細(動的ルート)
├── components/
├── lib/
└── public/

Server Componentsの活用

// app/blog/page.tsx - Server Componentの例
import { getPosts } from '@/lib/api';

// async/awaitが直接使える!
export default async function BlogPage() {
  const posts = await getPosts(); // サーバーサイドで実行
  
  return (
    <div>
      <h1>ブログ記事一覧</h1>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </article>
      ))}
    </div>
  );
}

// メタデータの動的生成
export async function generateMetadata({ params }: Props) {
  const post = await getPost(params.slug);
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [post.coverImage],
    },
  };
}

Client Componentsの使い方

'use client';

import { useState } from 'react';

// インタラクティブなコンポーネントはClient Component
export function SearchBar({ onSearch }: { onSearch: (q: string) => void }) {
  const [query, setQuery] = useState('');
  
  return (
    <div>
      <input
        value={query}
        onChange={e => setQuery(e.target.value)}
        placeholder="記事を検索..."
      />
      <button onClick={() => onSearch(query)}>検索</button>
    </div>
  );
}

データフェッチとキャッシュ戦略

// キャッシュなし(毎回フェッチ)
const data = await fetch('/api/data', { cache: 'no-store' });

// 静的生成(ビルド時にキャッシュ)
const data = await fetch('/api/data', { cache: 'force-cache' });

// 時間ベースの再検証(60秒ごとに更新)
const data = await fetch('/api/data', { 
  next: { revalidate: 60 } 
});

// タグベースのオンデマンド再検証
const data = await fetch('/api/posts', {
  next: { tags: ['posts'] }
});

// Webhook等でタグを無効化
import { revalidateTag } from 'next/cache';
revalidateTag('posts');

Vercelへのデプロイ手順

  • GitHubにコードをプッシュ
  • Vercel(vercel.com)にアクセスしてGitHubと連携
  • リポジトリを選択してインポート
  • 環境変数を設定(.env.localの内容)
  • 「Deploy」ボタンをクリックするだけで自動デプロイ完了

Next.jsを使ってWebアプリを作りたい方には、フリーランスエンジニア向け案件獲得ガイドも参考になります。

投稿者 kasata

IT企業でエンジニアとして勤務後、テクノロジー情報メディア「Tech Athletes(テック・アスリート)」を運営。プログラミング、クラウドインフラ(AWS/GCP/Azure)、AI活用、Webサービス開発を専門とする。エンジニア・ビジネスパーソン向けに、実際に使ってみた経験をもとに信頼できる技術情報を発信中。資格:AWS認定ソリューションアーキテクト、Python 3 エンジニア認定試験合格。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です