Welcome to Tech Athletes | テック・アスリート   Click to listen highlighted text! Welcome to Tech Athletes | テック・アスリート

【2026年最新】Next.js完全入門ガイド|App Router・Server Components・実践的なWebアプリ開発まで徹底解説

Next.jsはReactをベースにしたフルスタックフレームワークで、2026年現在、最も人気のあるWebフレームワークの一つです。本記事では、Next.js 15の主要機能から実践的なアプリ開発まで体系的に解説します。

Next.jsとは?Reactとの違い

Next.jsはVercelが開発するReactフレームワークです。Reactだけではフロントエンドしか構築できませんが、Next.jsはサーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、APIルート、App Routerなどを提供し、フルスタックアプリを構築できます。

Next.jsの主要な特徴

  • App Router:Next.js 13以降の新しいルーティングシステム。Server Componentsをデフォルトで使用
  • Server Components:サーバーサイドでコンポーネントを実行。データフェッチが高速
  • Server Actions:フォームの送信やデータ変更をサーバーで安全に処理
  • Image最適化:自動的にWebP変換・遅延読み込み・サイズ最適化
  • Turbopack:Rustベースの超高速バンドラーでビルドが爆速

Next.jsのセットアップ

# Next.jsプロジェクトの作成
npx create-next-app@latest my-next-app
# オプション選択画面
# ✅ TypeScript を使用
# ✅ ESLint を使用
# ✅ Tailwind CSSを使用
# ✅ App Router を使用
# ✅ src/ ディレクトリを使用

cd my-next-app
npm run dev  # 開発サーバー起動(http://localhost:3000)

プロジェクト構造

my-next-app/
├── src/
│   └── app/
│       ├── layout.tsx       # ルートレイアウト
│       ├── page.tsx         # トップページ
│       ├── loading.tsx      # ローディングUI
│       ├── error.tsx        # エラーUI
│       ├── not-found.tsx    # 404ページ
│       ├── blog/
│       │   ├── page.tsx     # /blog
│       │   └── [slug]/
│       │       └── page.tsx # /blog/:slug
│       └── api/
│           └── posts/
│               └── route.ts # /api/posts エンドポイント
├── public/              # 静的ファイル
├── next.config.ts       # Next.js設定
└── tailwind.config.ts   # Tailwind設定

Server ComponentsとClient Components

Next.js App Routerでは、デフォルトでServer Componentsを使用します。インタラクティブな機能(useState、useEffect、イベントハンドラー)が必要な場合はClient Componentsを使います。

// Server Component(デフォルト)
// app/blog/page.tsx

interface Post {
  id: number;
  title: string;
  excerpt: string;
  slug: string;
}

async function getPosts(): Promise<Post[]> {
  // サーバーサイドで直接データベースやAPIを呼び出せる
  const res = await fetch('https://api.example.com/posts', {
    next: { revalidate: 3600 } // 1時間キャッシュ
  });
  return res.json();
}

export default async function BlogPage() {
  const posts = await getPosts(); // サーバーで実行される
  
  return (
    <main>
      <h1>ブログ記事一覧</h1>
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
        {posts.map((post) => (
          <article key={post.id} className="border rounded-lg p-4">
            <h2 className="text-xl font-bold">{post.title}</h2>
            <p className="text-gray-600">{post.excerpt}</p>
            <a href={`/blog/${post.slug}`} className="text-blue-600 hover:underline">
              続きを読む
            </a>
          </article>
        ))}
      </div>
    </main>
  );
}
'use client'; // Client Componentの宣言

import { useState } from 'react';

interface SearchBarProps {
  onSearch: (query: string) => void;
}

export function SearchBar({ onSearch }: SearchBarProps) {
  const [query, setQuery] = useState('');
  
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    onSearch(query);
  };
  
  return (
    <form onSubmit={handleSubmit} className="flex gap-2">
      <input
        type="text"
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="記事を検索..."
        className="border rounded px-4 py-2 flex-1"
      />
      <button type="submit" className="bg-blue-600 text-white px-6 py-2 rounded">
        検索
      </button>
    </form>
  );
}

APIルートの実装

// app/api/posts/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { z } from 'zod';

const PostSchema = z.object({
  title: z.string().min(1).max(100),
  content: z.string().min(1),
  published: z.boolean().default(false)
});

// GET /api/posts
export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const page = parseInt(searchParams.get('page') ?? '1');
  const limit = parseInt(searchParams.get('limit') ?? '10');
  
  const posts = await prisma.post.findMany({
    where: { published: true },
    skip: (page - 1) * limit,
    take: limit,
    orderBy: { createdAt: 'desc' }
  });
  
  return NextResponse.json({ posts, page, limit });
}

// POST /api/posts
export async function POST(request: NextRequest) {
  const body = await request.json();
  const result = PostSchema.safeParse(body);
  
  if (!result.success) {
    return NextResponse.json(
      { error: result.error.issues },
      { status: 400 }
    );
  }
  
  const post = await prisma.post.create({ data: result.data });
  return NextResponse.json(post, { status: 201 });
}

Server Actions:フォーム送信を安全に処理

'use server'; // Server Actionsの宣言

import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { prisma } from '@/lib/prisma';
import { z } from 'zod';

const ContactSchema = z.object({
  name: z.string().min(1, '名前は必須です'),
  email: z.string().email('有効なメールアドレスを入力してください'),
  message: z.string().min(10, 'メッセージは10文字以上で入力してください')
});

export async function submitContactForm(formData: FormData) {
  const data = {
    name: formData.get('name') as string,
    email: formData.get('email') as string,
    message: formData.get('message') as string
  };
  
  const result = ContactSchema.safeParse(data);
  if (!result.success) {
    return { error: result.error.issues[0].message };
  }
  
  await prisma.contact.create({ data: result.data });
  
  // メール通知を送信
  await sendNotificationEmail(result.data);
  
  revalidatePath('/contact');
  redirect('/contact/thanks');
}

Next.jsのデプロイ

Vercelへのデプロイ(最も簡単)

# Vercel CLIでデプロイ
npm install -g vercel
vercel login
vercel --prod  # 本番デプロイ

# または GitHub連携で自動デプロイも可能

Docker + セルフホスティング

# next.config.ts
const nextConfig = {
  output: 'standalone', // Dockerデプロイ向けの設定
};

# Dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]

まとめ:Next.js学習ロードマップ

Next.jsはReactの知識を持つエンジニアが最初に学ぶべきフレームワークです。App Router・Server Components・Server Actionsなどの新機能を習得することで、フルスタック開発が可能になります。Udemyの「Next.js 15 & React完全ガイド」などのコースや、Vercelの公式ドキュメントを活用して学習を進めましょう。Next.jsの求人は増加しており、フロントエンドエンジニアの年収500万〜1,000万円以上を目指せる実践的なスキルです。

投稿者 kasata

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

コメントを残す

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

Click to listen highlighted text!