Next.js App Routerとは
Next.js 13から導入されたApp Routerは、React Server ComponentsをベースにしたNext.jsの新しいルーティングシステムです。従来のPages Routerと異なり、サーバーサイドレンダリングをデフォルトとし、よりパフォーマンスと開発者体験に優れています。
プロジェクト作成と基本構成
npx create-next-app@latest my-app --typescript --tailwind --eslint --app
cd my-app
npm run dev
App Routerのディレクトリ構成
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/
users/
route.ts # API Route Handler
components/ # コンポーネント
lib/ # ユーティリティ
public/ # 静的ファイル
Server Componentsの活用
// app/blog/page.tsx - デフォルトでServer Component
import { db } from '@/lib/db';
// データをサーバーサイドで直接取得
async function BlogListPage() {
// データベースに直接アクセス(APIを経由しない)
const posts = await db.post.findMany({
orderBy: { createdAt: 'desc' },
take: 10,
include: { author: true, category: true }
});
return (
ブログ記事一覧
{posts.map(post => (
-
{post.title}
{post.excerpt}
{post.author.name} | {post.createdAt.toLocaleDateString('ja-JP')}
))}
);
}
export default BlogListPage;
Server Actions|フォーム処理の新しい方法
// app/contact/actions.ts
'use server';
import { z } from 'zod';
import { revalidatePath } from 'next/cache';
const ContactSchema = z.object({
name: z.string().min(1, '名前は必須です'),
email: z.string().email('有効なメールアドレスを入力してください'),
message: z.string().min(10, 'メッセージは10文字以上で入力してください')
});
export async function submitContact(formData: FormData) {
const validatedFields = ContactSchema.safeParse({
name: formData.get('name'),
email: formData.get('email'),
message: formData.get('message')
});
if (!validatedFields.success) {
return { errors: validatedFields.error.flatten().fieldErrors };
}
// データベースに保存
await db.contact.create({ data: validatedFields.data });
// キャッシュを再検証
revalidatePath('/admin/contacts');
return { success: true };
}
キャッシュ戦略
// 静的データのキャッシュ(デフォルト)
const data = await fetch('https://api.example.com/data');
// 再検証間隔の設定(60秒ごとに再取得)
const data = await fetch('https://api.example.com/data', {
next: { revalidate: 60 }
});
// キャッシュを無効化(常に最新データを取得)
const data = await fetch('https://api.example.com/data', {
cache: 'no-store'
});
// タグベースのキャッシュ
const data = await fetch('https://api.example.com/posts', {
next: { tags: ['posts'] }
});
// 特定タグのキャッシュを無効化
revalidateTag('posts');
本番デプロイ(Vercel)
# Vercel CLIでデプロイ
npm install -g vercel
vercel login
vercel # 初回デプロイ
vercel --prod # 本番デプロイ
# または GitHub連携で自動デプロイ
# 1. GitHubにプッシュ
# 2. Vercelでリポジトリを接続
# 3. mainブランチへのpushで自動デプロイ
まとめ
Next.js App Routerは、パフォーマンス・開発体験・SEO最適化において従来のアーキテクチャを大きく上回ります。Server Components・Server Actions・高度なキャッシュ戦略を組み合わせることで、高速で保守性の高いWebアプリケーションを構築できます。