Next.js 15完全ガイド:App RouterとServer Componentsで作るモダンWebアプリ

Next.js 15は、Reactアプリケーション開発のための最先端フレームワークとして、2024年にリリースされました。App Router、React Server Components、強化されたキャッシュ機能など、モダンなWeb開発に必要な機能が充実しています。本記事では、Next.js 15の主要な機能と、実際のWebアプリ開発における活用方法をステップバイステップで解説します。

Next.js 15の主な新機能と改善点

Next.js 15では、いくつかの重要な変更と新機能が導入されました。最も注目すべきは、React 19のサポートとそれに伴うServer Actionsの安定化、キャッシュ動作のデフォルト設定の変更、Turbopackのstable化です。これらの変更により、開発体験とパフォーマンスが大幅に向上しています。

React 19サポートと非同期リクエストAPIの変更

Next.js 15ではReact 19が正式サポートされ、新しい非同期APIが導入されました。特に重要なのは、cookiesやheadersなどのリクエストAPIが非同期化されたことです。これにより、サーバーコンポーネントでのデータアクセスがより明示的になりました。

// Next.js 15での新しい書き方(非同期)
import { cookies } from 'next/headers';

export async function getData() {
  const cookieStore = await cookies(); // awaitが必要になった
  const token = cookieStore.get('token');
  return token;
}

キャッシュ動作のデフォルト変更

Next.js 15では、fetchリクエストとRoute Handlersのデフォルトキャッシュ動作が変更されました。以前は自動的にキャッシュされていたfetchが、デフォルトでキャッシュなし(no-store)に変更されています。これはよりシンプルで予測可能な動作を実現するためですが、既存アプリを移行する際は注意が必要です。

// キャッシュを有効にする場合は明示的に設定
const data = await fetch('https://api.example.com/data', {
  cache: 'force-cache', // または next: { revalidate: 3600 }
});

// キャッシュなし(デフォルト動作)
const data = await fetch('https://api.example.com/data');
// 上記は cache: 'no-store' と同等

App Routerの理解と活用

App RouterはNext.js 13で導入され、Next.js 15でさらに安定・成熟しました。Pages Routerと異なり、appディレクトリ内のフォルダ構造がそのままURLパスになる規約ベースのルーティングシステムです。ファイルベースのルーティング、レイアウトの入れ子構造、サーバーコンポーネントのデフォルト化など、モダンなアプリ構造を実現します。

// ディレクトリ構造例
app/
├── layout.tsx      // ルートレイアウト(全ページ共通)
├── page.tsx        // / (トップページ)
├── about/
│   └── page.tsx    // /about
├── blog/
│   ├── page.tsx    // /blog
│   └── [slug]/
│       └── page.tsx // /blog/:slug (動的ルート)
└── api/
    └── users/
        └── route.ts // /api/users (APIエンドポイント)

特殊ファイルの役割

App Routerでは、特定のファイル名が特別な意味を持ちます。page.tsx はそのルートのUIを担当するページコンポーネントです。layout.tsx はそのルートとその子ルートで共有されるレイアウトです。loading.tsx はページの読み込み中に表示されるUI(React Suspenseとの連携)です。error.tsx はエラーが発生した際のフォールバックUIです。not-found.tsx は404エラー時のUIを定義します。これらを組み合わせることで、優れたユーザー体験を提供できます。

Server ComponentsとClient Components

Next.js(App Router)の最重要概念のひとつが、Server ComponentsとClient Componentsの使い分けです。App Routerでは、デフォルトでコンポーネントはServer Componentsとして扱われます。

Server Componentsの利点

Server Componentsはサーバーサイドでレンダリングされるコンポーネントで、以下の特徴があります。データベースやAPIに直接アクセスできます(セキュアなAPIキーを安全に使用可能)。バンドルサイズを削減できます(クライアントに送信するJavaScriptを減らせる)。初期ページロードが高速です(サーバーでHTMLを生成して送信)。APIキーなどの秘密情報をブラウザに公開せずに使用できます。ただし、onClickなどのイベントハンドラー、useStateなどのReact Hooksは使用できません。

// Server Component(デフォルト - "use server"は不要)
// app/blog/[slug]/page.tsx
import { getPost } from '@/lib/posts';

// async/awaitで直接データフェッチが可能
export default async function BlogPost({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug); // サーバーでDBアクセス
  
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

Client Componentsの活用場面

ユーザーインタラクション(クリック、フォーム入力など)、ブラウザAPIの使用、Reactのstate管理やエフェクトが必要な場合は、’use client’ディレクティブを使ってClient Componentsにする必要があります。

'use client'; // このディレクティブでClient Componentになる

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0); // useStateはClient Componentでのみ使用可
  
  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        増やす
      </button>
    </div>
  );
}

データフェッチのベストプラクティス

Next.js 15では、データフェッチの方法が大きく進化しています。Server Componentsを使うことで、コンポーネント内で直接async/awaitを使ったデータフェッチが可能です。これにより、従来のgetServerSidePropsやgetStaticPropsと比べて、よりシンプルで直感的なコードが書けます。

// 並列データフェッチ(パフォーマンス最適化)
export default async function Dashboard() {
  // Promise.allで並列フェッチ(待ち時間を最小化)
  const [userData, postsData] = await Promise.all([
    fetch('https://api.example.com/user').then(r => r.json()),
    fetch('https://api.example.com/posts').then(r => r.json()),
  ]);
  
  return (
    <div>
      <UserProfile user={userData} />
      <PostList posts={postsData} />
    </div>
  );
}

Server Actionsによるフォーム処理

Server ActionsはNext.js 15(React 19)で安定化された機能で、クライアントから直接サーバー側の関数を呼び出すことができます。フォームの送信処理をAPIエンドポイントを作らずにサーバー側で直接処理できるため、コードが大幅にシンプルになります。

// Server Action(server側で実行される関数)
'use server';

import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';

export async function createPost(formData: FormData) {
  const title = formData.get('title') as string;
  const content = formData.get('content') as string;
  
  // DBに直接書き込み(APIエンドポイント不要)
  await db.post.create({ data: { title, content } });
  
  revalidatePath('/blog'); // キャッシュを更新
  redirect('/blog');       // リダイレクト
}

// フォームコンポーネント(Client Component不要)
export default function CreatePostForm() {
  return (
    <form action={createPost}> {/* Server Actionを直接指定 */}
      <input name="title" placeholder="タイトル" required />
      <textarea name="content" placeholder="内容" required />
      <button type="submit">投稿</button>
    </form>
  );
}

パフォーマンス最適化テクニック

Next.js 15には多くのパフォーマンス最適化機能が組み込まれています。画像最適化については、next/imageコンポーネントを使うことで、自動的に適切なサイズへのリサイズ、WebP/AVIFフォーマットへの変換、遅延読み込みが適用されます。フォントについても、next/fontを使うことでGoogle Fontsなどのカスタムフォントが最適化され、レイアウトシフト(CLS)を防ぎます。コード分割については、App Routerを使うことで自動的にルートごとのコード分割が行われ、初期ロードを高速化します。

まとめ:Next.js 15で始めるモダンWeb開発

Next.js 15はApp Router、Server Components、Server Actions、Turbopackなど、モダンなWeb開発に必要な機能を統合した強力なフレームワークです。React 19のサポートにより、さらに使いやすく、パフォーマンスの高いWebアプリケーションの構築が可能になっています。

本記事で紹介した機能を活用することで、サーバーサイドレンダリング、静的生成、インクリメンタル静的再生成などの戦略を組み合わせた高品質なWebアプリが構築できます。Next.js 15の公式ドキュメントと豊富なコミュニティリソースを活用しながら、実際のプロジェクトで試してみてください。モダンWeb開発の世界は日々進化しており、Next.jsはその最前線で活躍し続けています。

投稿者 kasata

コメントを残す

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