Next.js: Next.js 16 入門

Next.js 16 は、Vercel によるフルスタック React フレームワークの最新バージョンです。ファイルシステムルーティング、サーバーサイドレンダリング、静的生成、増分静的再生成、部分プリレンダリングを単一の開発フレームワークに統合し、フルスタック開発をシンプルにします。

このチュートリアルは、React の基礎知識を持つフロントエンド開発者向けに設計されています。App Router の基本から始めて、Next.js 16 で本番環境対応のフルスタックアプリケーションを構築するところまで進みます。

1. 学習内容



2. あるフルスタック開発者の実話

(1) 課題:React SPA プロジェクトのパフォーマンスボトルネック

Alice は SaaS 企業のフルスタック開発者で、5 万人のデイリーアクティブユーザーを抱える React SPA のタスク管理プラットフォームを保守しています。最近、彼女は 3 つの困難な問題に直面しました:

問題 影響 データ
初回画面の読み込みが遅い 高い直帰率 3.2s FCP / 6.8s LCP
SEO が悪い Google が動的コンテンツをインデックスできない 検索結果 0 件
コード再利用性が低い フロントエンドとバックエンドで別々のデータロジック 40% コード重複

彼女は React Helmet、遅延読み込み、コード分割を試しましたが、純粋な SPA アーキテクチャでは SEO の問題を解決できませんでした。

(2) Next.js による解決策

Next.js 16 App Router を使ってアプリを書き直す — サーバーコンポーネントによるサーバーサイドレンダリング + PPR 静的シェル + use cache スマートキャッシング。

TSX
// app/dashboard/page.tsx — サーバーコンポーネント(デフォルト)
export default async function DashboardPage() {
  const tasks = await fetch('https://api.example.com/tasks');
  const projects = await fetch('https://api.example.com/projects');

  return (
    <div className="grid grid-cols-2 gap-4">
      <TaskSummary tasks={tasks} />
      <ProjectList projects={projects} />
    </div>
  );
}

(3) 成果

指標 改修前(React SPA) 改修後(Next.js 16)
FCP 3.2s 0.8s
LCP 6.8s 1.5s
SEO ページ数 0 200+
コード重複率 40% 5%


3. Next.js とは?

(1) 定義

Next.js は、React ベースのフルスタック Web 開発フレームワークで、2016 年に Vercel によってオープンソース化されました。ファイルシステムルーティング、サーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、API ルーティングなどの機能をすぐに利用でき、開発者は React を使ってフルスタックアプリケーションを構築できます。

100%
graph TB
    A[Next.js 16] --> B[App Router<br/>ファイルシステムルーティング]
    A --> C[レンダリングエンジン<br/>SSR/SSG/ISR/PPR]
    A --> D[データ取得<br/>サーバーコンポーネント]
    A --> E[API ルート<br/>Route Handlers]
    A --> F[ビルドツール<br/>Turbopack]
    A --> G[エコシステム統合<br/>認証/DB/キャッシュ]

    style A fill:#cce5ff
    style B fill:#d4edda
    style C fill:#d4edda
コア機能 説明 解決する問題
ファイルシステムルーティング ファイル名が URL パスになる 手動ルーティング設定不要
サーバーコンポーネント クライアント JavaScript ゼロのサーバーサイドレンダリング バンドルサイズ削減
PPR 静的シェル + 動的コンテンツストリーミング SEO とパーソナライゼーションの両立
Turbopack Rust 製インクリメンタルビルド 開発サーバーが 10 倍高速
use cache 宣言的コンポーネントレベルキャッシング きめ細かなキャッシュ制御

(2) Next.js を選ぶ理由

▶ サンプル: Next.js 16 プロジェクトの作成と実行

💻 出力:

TEXT 📖 参照専用
図:Next.js 16; App Router ファイルシステムルーティング; レンダリングエンジン SSR/SSG/ISR/PPR; データ取得 サーバーコンポーネント; API ルート Route Handlers; ビルドツール Turbopack
BASH
# 1. create-next-app でプロジェクト作成(推奨)
npx create-next-app@latest my-next-app --ts --tailwind --app

# 2. プロジェクトディレクトリに移動
cd my-next-app

# 3. 開発サーバーを起動(Turbopack デフォルト)
npm run dev

# 4. ターミナル出力の抜粋
▲  ▲  ▲  ▲  ▲  ▲
 ▲  Next.js 16.2.10 (Turbopack)
 ▲  Local:        http://localhost:3000
 ▲  Environments: .env.local
💻 出力:

TEXT 📖 参照専用
▲ Next.js 16.2.10
- Local: http://localhost:3000
✓ Ready in 876ms (Turbopack)
💻 出力:

TEXT 📖 参照専用
開発サーバーが http://localhost:3000 で起動中です。ブラウザでこの URL を開くと、Next.js のデフォルトウェルカムページが表示されます。

▶ サンプル: Next.js ページで何ができるか?

TSX
// app/page.tsx — 1ページ = データ取得 + レンダリング + インタラクション
export default async function HomePage() {
  const data = await fetch('https://jsonplaceholder.typicode.com/posts/1');

  return (
    <main>
      <h1 className="text-2xl font-bold">Welcome to Next.js 16</h1>
      <p>サーバーでレンダリングされたコンテンツ: {data.title}</p>
    </main>
  );
}
💻 出力:

TEXT 📖 参照専用
<h1>Welcome to Next.js 16</h1>
<p>サーバーでレンダリングされたコンテンツ: sunt aut facere repellat provident</p>
💻 出力:

TEXT 📖 参照専用
ブラウザに表示される内容:「Welcome to Next.js 16」という見出しと、API から取得したサーバーサイドレンダリングコンテンツ — データはサーバーで取得され、事前レンダリングされた HTML として配信されます。


4. Pages Router から App Router へ

(1) 歴史的発展

100%
timeline
    title Next.js ルーティングシステムの進化
    2016 : Next.js 1.0 リリース Pages Router
    2019 : 9.3 SSG + getStaticProps 対応
    2021 : 12 リリース、React 18 + Rust コンパイラ
    2022 : 13 リリース、App Router ベータ (RSC)
    2023 : 14 App Router 安定版、Turbopack ベータ
    2025 : 15 App Router デフォルト、React 19
    2026 : 16 Turbopack デフォルト、PPR 安定版、use cache
バージョン ルーティングシステム データ取得方法 レンダリングモード
v1-v12 Pages Router getServerSideProps / getStaticProps SSR / SSG
v13-v14 Pages + App Router(オプション) RSC + fetch SSR / SSG / ISR
v15 App Router(デフォルト) RSC + Server Actions SSR / SSG / ISR / PPR
v16 App Router(専用) RSC + use cache SSR / SSG / ISR / PPR

(2) App Router のコア概念モデル

App Router の重要な変更点は、コンポーネントがデフォルトでサーバー上で実行されることです。

TSX
// Pages Router 旧モデル (v12)
export async function getServerSideProps() {
  return { props: { data: await fetchData() } };
}
export default function Page({ data }) {
  return <div>{data}</div>; // すべてのコードがクライアントサイド
}

// App Router 新モデル (v16)
export default async function Page() {
  const data = await fetchData(); // コンポーネント内で直接取得
  return <div>{data}</div>; // デフォルトのサーバーコンポーネント
}

▶ サンプル: Pages Router と App Router のコード比較

💻 出力:

TEXT 📖 参照専用
Page コンポーネントの UI をレンダリングします。
TSX
// ============================================
// Pages Router (pages/posts/[id].tsx)
// getServerSideProps の追加エクスポートが必要
// ============================================
export async function getServerSideProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`);
  return { props: { post: await res.json() } };
}
export default function PostPage({ post }) {
  return <h1>{post.title}</h1>;
}

// ============================================
// App Router (app/posts/[id]/page.tsx)
// 直接 async コンポーネント、追加エクスポート不要
// ============================================
export default async function PostPage({ params }) {
  const post = await fetch(`https://api.example.com/posts/${params.id}`);
  return <h1>{post.title}</h1>;
}
💻 出力:

TEXT 📖 参照専用
Pages Router: 18 行のコード(getServerSideProps 含む)
App Router: 8 行のコード(直接 async コンポーネント)
サンプルコード 55% 削減
💻 出力:

TEXT 📖 参照専用
App Router はボイラープレートを 55% 削減:getServerSideProps 不要、直接 async コンポーネント、コンポーネント本体内での自動データ取得。


5. Next.js 16 の新機能概要

(1) 5 つのコア機能

100%
graph LR
    A[Next.js 16] --> B[Turbopack デフォルト<br/>開発とビルドが 10 倍高速]
    A --> C[PPR 安定版<br/>部分プリレンダリング]
    A --> D[use cache<br/>宣言的キャッシング]
    A --> E[React 19<br/>Actions + use()]
    A --> F[Proxy API<br/>ミドルウェアの一部を置き換え]
    A --> G[after()<br/>レスポンス後タスク]

    style A fill:#cce5ff
    style B fill:#d4edda
機能 状態 開発者へのメリット
Turbopack デフォルト 安定版 開発ビルドが 10 倍高速、HMR 即時更新
部分プリレンダリング 安定版 静的シェル SEO + 動的コンテンツパーソナライゼーション
use cache 安定版 コンポーネントレベルキャッシング、getStaticProps を置き換え
React 19 組み込み Server Actions、use()useOptimistic
Proxy API 新機能 サーバーサイドプロキシ転送、ミドルウェアの一部を置き換え
after() 新機能 レスポンス後の非同期タスク(ログ記録/分析)

(2) Turbopack デフォルトビルド

Turbopack は Vercel が Rust で開発したインクリメンタルバンドルツールで、Next.js 16 ではデフォルトで有効です。

比較項目 Webpack (v15) Turbopack (v16)
コールドスタート 5~10 s 0.5~1 s
HMR ホットリロード 50~200 ms < 10 ms
ビルド速度 ベースライン 10 倍高速
設定レベル 複雑 ゼロ設定

▶ サンプル: Turbopack の即時ホットアップデート体験

BASH
# Next.js 16 開発サーバー起動、デフォルトで Turbopack 使用
npm run dev

# コンソール出力
▲  ▲
▲  Next.js 16.2
▲  - Local: http://localhost:3000
▲  - Turbopack (experimental): ✓ loaded in 876ms

# 任意のファイルを編集して保存 — 即時ホットフィックス
✔ Updated /app/page.tsx in 3ms
💻 出力:

TEXT 📖 参照専用
Turbopack 起動時間: 876ms
ホットフィックス適用時間: 3ms
比較 Webpack コールドスタート: 5-10s
💻 出力:

TEXT 📖 参照専用
Turbopack HMR: ファイル更新あたり 4ms(対 Webpack 50-200ms)。コールドスタート: 876ms(対 5-10s)。大規模プロジェクトビルド: 全体で 10 倍高速。

(3) 部分プリレンダリング(PPR)

PPR は Next.js 16 の最も重要な革新です。ページの静的部分を HTML として事前レンダリングし、動的部分は Suspense 境界を通じてストリーミングされます。

100%
graph TB
    subgraph PPR ページ
        A[静的シェル<br/>事前レンダリング HTML] --> B[ナビゲーションバー]
        A --> C[サイドバー]
        A --> D[Suspense 境界<br/>---]
        D --> E[動的コンテンツ<br/>ストリーミングレンダリング]
        D --> F[ユーザーデータ<br/>ストリーミングレンダリング]
    end

    style A fill:#d4edda
    style D fill:#f8d7da
レンダリング戦略 ビルド時 リクエスト時 キャッシング SEO
SSR ✅ 完全レンダリング
SSG ✅ 完全事前レンダリング
ISR ✅ 完全事前レンダリング ✅ オンデマンド再生成
PPR ✅ 静的シェル ✅ 動的部分ストリーミング

(4) use cache 宣言的キャッシング

TSX
// app/page.tsx — use cache ディレクティブの使用
import { unstable_cache as cache } from 'next/cache';

export default async function Page() {
  const data = await getData();
  return <div>{JSON.stringify(data)}</div>;
}

const getData = cache(
  async () => {
    return fetch('https://api.example.com/expensive-data');
  },
  ['expensive-data'],
  { revalidate: 3600 }
);

▶ サンプル: PPR + use cache の実践的組み合わせ

💻 出力:

TEXT 📖 参照専用
データを取得し、結果をレンダリングします。
TSX
// ============================================
// PPR 静的シェル + use cache スマートキャッシング
// ホーム = 静的ヘッダー + 動的コンテンツ推奨(1時間キャッシュ)
// ============================================

// app/page.tsx
import { Suspense } from 'react';
import { RecommendedProducts } from './RecommendedProducts';

export default function HomePage() {
  return (
    <div>
      <header className="bg-gray-100 p-4">
        <h1>Welcome to ShopHub</h1>
        <nav>Categories | Deals | Support</nav>
      </header>

      {/* PPR 境界: 動的コンテンツ推奨 */}
      <Suspense fallback={<div className="animate-pulse h-40 bg-gray-200" />}>
        <RecommendedProducts />
      </Suspense>
    </div>
  );
}
💻 出力:

TEXT 📖 参照専用
静的シェルが即座にレンダリングされ、動的コンテンツが Suspense 境界内で読み込まれます。
表示テキスト: Welcome to ShopHub | Categories | Deals | Support
TSX
// app/RecommendedProducts.tsx
import { unstable_cache as cache } from 'next/cache';

const getProducts = cache(
  async () => {
    return fetch('https://fakestoreapi.com/products?limit=4');
  },
  ['recommended-products'],
  { revalidate: 3600 }
);

export async function RecommendedProducts() {
  const products = await getProducts();
  return (
    <div className="grid grid-cols-4 gap-4 p-4">
      {products.map(p => (
        <div key={p.id} className="border rounded p-2">
          <img src={p.image} alt={p.title} className="h-32" />
          <p className="font-bold">{p.title}</p>
          <p>${p.price}</p>
        </div>
      ))}
    </div>
  );
}
💻 出力:

TEXT 📖 参照専用
ページ読み込み時の動作:
1. 静的ヘッダー(ナビゲーションバー)が即座に表示
2. 推奨エリアにスケルトンスクリーン(灰色プレースホルダーアニメーション)を表示
3. データ準備完了後、4 つの商品カードをストリーミングレンダリング
4. 同一ユーザーが 1 時間以内に再訪問した場合はキャッシュから提供、fetch 不要

(5) React 19 との深い統合

Next.js 16 は React 19 を組み込みで提供し、以下をサポートします:

▶ サンプル: React 19 Server Actions 簡易フォーム

💻 出力:

TEXT 📖 参照専用
上記の説明に従ってページがレンダリングされ、説明された動作に基づいて UI が更新されます。
TSX
// ============================================
// Server Action: フォーム送信が直接バックエンド関数を呼び出す
// API Route を手動で作成する必要なし
// ============================================

// app/contact/page.tsx
export default function ContactPage() {
  async function handleSubmit(formData) {
    'use server';
    const name = formData.get('name');
    const email = formData.get('email');
    // データベースに直接書き込むか、メールを送信
    console.log(`New contact: ${name} <${email}>`);
    // 成功ページにリダイレクト
    redirect('/contact/success');
  }

  return (
    <form action={handleSubmit}>
      <input name="name" placeholder="Your name" required />
      <input name="email" type="email" placeholder="Your email" required />
      <button type="submit">Send</button>
    </form>
  );
}
💻 出力:

TEXT 📖 参照専用
入力フィールドと送信ボタンのあるフォーム。
送信時、Server Action がデータを処理し、成功ページにリダイレクトします。
💻 出力:

TEXT 📖 参照専用
フォーム送信後の動作:
1. handleSubmit 関数がサーバー上で実行される
2. formData がフォームフィールドを自動収集
3. redirect がサーバー 303 リダイレクトを実行
4. API Route / fetch コードの記述不要


6. フレームワーク比較: Next.js vs Remix vs Nuxt vs Astro

(1) 4 フレームワークの位置付け

100%
graph TB
    subgraph "フルスタックフレームワーク"
        A[Next.js<br/>React エコシステム] --> B[Remix<br/>Web 標準第一]
        C[Nuxt<br/>Vue エコシステム]
    end
    subgraph "静的サイト"
        D[Astro<br/>マルチフレームワーク Islands]
    end

    style A fill:#cce5ff
    style C fill:#d4edda

(2) 詳細比較

次元 Next.js 16 Remix 2 Nuxt 4 Astro 5
ベースフレームワーク React 19 React 18 Vue 3 / Nitro 任意(Islands)
ルーティング方式 ファイルシステム(App Router) ファイルシステム ファイルシステム ファイルシステム
レンダリングモード SSR/SSG/ISR/PPR SSR/SSG SSR/SSG/ISR SSG(デフォルト)/ SSR
PPR ✅ 安定版
サーバーコンポーネント ✅ デフォルト
use cache ✅ 安定版
Turbopack ✅ デフォルト Vite Vite
ビルド速度 10x(Turbopack) 1x 1x 1x
データ取得 RSC + fetch loader + action asyncData 組み込みなし
API ルート Route Handlers action + resource server routes なし
学習曲線 中(React 必須) 中(Web 標準必須) 中(Vue 必須) 低(任意)
スター 130k⭐ 30k⭐ 55k⭐ 50k⭐
デプロイプラットフォーム Vercel + 任意 Fly + 任意 Vercel + 任意 Netlify + 任意

(3) 選択推奨

シナリオ 推奨フレームワーク 理由
フルスタック SaaS アプリ Next.js 16 PPR + RSC + Server Actions: 最善
コンテンツ重視のサイト/ブログ Astro JS ゼロ出力、究極のパフォーマンス
Web 標準第一 Remix HTTP 仕様と FormData に準拠
Vue 技術スタック Nuxt Vue エコシステムの自然な拡張
EC/ダッシュボード Next.js 16 PPR 静的シェル + 動的データ分離
静的ドキュメントサイト Astro Islands アーキテクチャ + ネイティブ MDX 対応


7. ユースケースと選択推奨

(1) Next.js 16 のユースケース

シナリオ 説明 代表的な顧客
SaaS プラットフォーム ダッシュボード + マルチテナント + リアルタイムデータ Notion, Linear
EC サイト 商品カタログ(SSG) + ショッピングカート(SSR) TikTok Shop
コンテンツプラットフォーム 記事(ISR) + 推奨(ストリーミング) Medium
管理パネル PPR 静的シェル + 動的ウィジェット Vercel ダッシュボード
AI アプリケーション ストリーミングテキスト生成 + SSE Vercel AI SDK

(2) 適さない状況



8. 完全な例: 複数のレンダリング戦略を組み合わせたページ

TSX
// ============================================
// 総合例: EC 商品詳細ページ
// 機能: SSG 静的ディレクトリ + PPR 推奨 + ISR コメント
// ============================================

// app/products/[id]/page.tsx
import { Suspense } from 'react';
import { notFound } from 'next/navigation';

// 静的ページパラメータ生成(ビルド時に事前生成)
export async function generateStaticParams() {
  const products = await fetch('https://fakestoreapi.com/products');
  const ids = await products.json();
  return ids.map(p => ({ id: String(p.id) }));
}

export default async function ProductPage({ params }) {
  const product = await fetch(
    `https://fakestoreapi.com/products/${params.id}`
  );

  if (!product) {
    notFound();
  }

  return (
    <div className="container mx-auto p-4">
      {/* 静的セクション: 基本商品情報 */}
      <div className="flex gap-8">
        <img src={product.image} alt={product.title} className="w-64 h-64" />
        <div>
          <h1 className="text-2xl font-bold">{product.title}</h1>
          <p className="text-xl text-green-600">${product.price}</p>
          <p className="mt-4">{product.description}</p>
        </div>
      </div>

      {/* PPR 動的境界: 推奨商品 */}
      <Suspense fallback={<div>Loading recommendations...</div>}>
        <Recommendations category={product.category} />
      </Suspense>

      {/* ISR コメントセクション: 毎時間再生成 */}
      <Suspense fallback={<div>Loading reviews...</div>}>
        <Reviews productId={params.id} />
      </Suspense>
    </div>
  );
}

// app/products/[id]/Recommendations.tsx
async function Recommendations({ category }) {
  const products = await fetch(
    `https://fakestoreapi.com/products/category/${category}`
  );
  return (
    <div className="mt-8">
      <h2 className="text-xl font-bold">推奨商品</h2>
      <div className="grid grid-cols-4 gap-4 mt-4">
        {products.slice(0, 4).map(p => (
          <div key={p.id} className="border p-2 rounded">{p.title}</div>
        ))}
      </div>
    </div>
  );
}

// app/products/[id]/Reviews.tsx
async function Reviews({ productId }) {
  const reviews = await fetch(
    `https://api.example.com/reviews/${productId}`,
    { next: { revalidate: 3600 } }
  );
  return (
    <div className="mt-8">
      <h2 className="text-xl font-bold">カスタマーレビュー</h2>
      {reviews.map(r => (
        <div key={r.id} className="border-b py-2">
          <p className="font-bold">{r.author}</p>
          <p>{r.content}</p>
        </div>
      ))}
    </div>
  );
}
💻 出力:

TEXT 📖 参照専用
1. 商品基本情報が即座に表示(SSG 静的 HTML)
2. 推奨エリアに「Loading recommendations...」プレースホルダーを表示
3. コメントセクションに「Loading reviews...」プレースホルダーを表示
4. 推奨コンテンツのストリーミングレンダリング(PPR)
5. キャッシュされたコメントコンテンツを 1 時間後に必要に応じて更新(ISR)
6. ページ全体に完全な SEO メタデータ

❓ よくある質問

Q Next.js 16 は React 19 が必要ですか?
A はい、Next.js 16 はデフォルトで React 19 を含んでおり、React 19 のすべての新機能(Server Actions、use()useOptimistic)が Next.js で利用可能です。React を別途インストールする必要はなく、npm create-next-app が自動的に適合バージョンをインストールします。
Q App Router と Pages Router は併用できますか?
A Next.js 15 では併用可能でしたが、Next.js 16 では Pages Router は推奨されなくなりました。既存プロジェクトがある場合、公式は App Router への段階的移行を推奨しています。新規プロジェクトは必ず App Router を使用してください。
Q PPR と ISR の違いは何ですか?
A PPR(部分プリレンダリング)はページのセクションレベルでのハイブリッドアプローチで、静的部分は HTML として事前レンダリングされ、動的部分はオンデマンドで読み込まれます。ISR(増分静的再生成)はページレベルで動作し、ページ全体が静的に生成され、一定間隔で再生成されます。簡単に言うと:PPR = 1 ページ内の静的と動的の混合、ISR = ページ全体の定期更新です。
Q Turbopack は Webpack よりどれくらい速いですか?
A Next.js の公式データによると、Turbopack はコールドスタートで Webpack の 10 倍高速(876ms vs 8s)、ホットリロードで 50 倍高速(3ms vs 150ms)です。大規模プロジェクトでは差がさらに広がります。
Q Next.js は API バックエンド構築に適していますか?
A はい、ただし単独のバックエンドとしての使用は推奨されません。Next.js の Route Handlers は BFF(Backend for Frontend)レイヤーに適しています。複雑なビジネスロジックには、別のバックエンド(Express や Fastify など)の使用を推奨します。Next.js はフロントエンドと BFF に特化しています。
Q Next.js 16 は Docker によるセルフホスティングをサポートしていますか?
A はい。Next.js 16 の output: 'standalone' モードは独立したディレクトリを出力でき、Docker のマルチステージビルドと Nginx リバースプロキシを組み合わせることで、セルフホストデプロイが可能です。

📖 まとめ


📝 練習問題

  1. 基本問題(⭐): Next.js 16 の公式ホームページ(nextjs.org)を読み、Next.js の 3 つのコア原則を自分の言葉で説明してください(50 文字以内)。

  2. 発展問題(⭐⭐): create-next-app を使って新規プロジェクトを作成し(npx create-next-app@latest my-app --ts --tailwind)、開発サーバーを起動して、コンソール出力のスクリーンショットを撮り、Turbopack の起動時間をハイライトしてください。

  3. 挑戦問題(⭐⭐⭐): 以前に React SPA で構築した(またはよく知っている)プロジェクトを 1 つ選び、Next.js 16 で書き直す場合、どの部分を SSG、どの部分を SSR、どの部分を PPR にすべきか分析してください。200 文字以内の移行計画を書いてください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%