こんにちは。
今回は、この企業ページのリポジトリをNext.js 13から15にアップデートしたので、その際に必要だった手順についてまとめてみました。
Next.js 13から15への移行ガイド
Next.js 13で導入されたApp Router(app/
ディレクトリを用いたルーティング)は、Next.js 13.4.0で正式に標準となりました。本記事では、Next.js 13から15への移行時に押さえておくべき技術的ポイントや具体的な移行手順について解説します。
1. ファイル構成の変更(Pages Router → App Router)
📌 変更点
pages/
ディレクトリを廃止し、app/
ディレクトリを使用。- ルーティングはファイル名ではなくディレクトリ構造で決まる。
page.tsx
(ページコンポーネント)を各ディレクトリ内に配置。layout.tsx
を用いてページ間で共通レイアウトを適用。
📝 移行前後のディレクトリ構成
従来のPages Router
pages/
├── _app.tsx
├── _document.tsx
├── index.tsx ("/"ページ)
├── about.tsx ("/about"ページ)
├── posts/
│ └── [id].tsx ("/posts/:id"ページ)
└── api/
└── hello.ts (APIエンドポイント)
新しいApp Router
app/
├── layout.tsx (Root Layout)
├── page.tsx ("/"ページ)
├── about/
│ └── page.tsx ("/about"ページ)
├── posts/
│ └── [id]/
│ └── page.tsx ("/posts/:id"ページ)
└── api/
└── hello/
└── route.ts (APIエンドポイント)
🛠 移行手順
app/
ディレクトリを作成。pages/_app.tsx
とpages/_document.tsx
の内容をapp/layout.tsx
に移行。- 各ページを対応する
app/
配下にpage.tsx
として配置。 pages/api/
のAPIルートをapp/api/
内にroute.ts
として移行。
2. API Routesの変更(pages/api/ → app/api/)
📌 変更点
pages/api/
をapp/api/
に移動。- APIエンドポイントの定義は
route.ts
ファイル内に記述。 req, res
ではなく、Request
オブジェクトとNextResponse
を使用。
📝 移行前後のAPIルート
従来のAPIルート
pages/api/hello.ts
// pages/api/hello.ts
import { NextApiRequest, NextApiResponse } from 'next';
export default function handler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).json({ message: 'Hello World' });
}
新しいAPIルート
app/api/hello/route.ts
// app/api/hello/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
return NextResponse.json({ message: 'Hello World' }, { status: 200 });
}
🛠 移行手順
pages/api/
の各ファイルをapp/api/
配下に移動。- ファイル名を
route.ts
に変更。 req, res
の処理をNextResponse
で置き換え。
3. Server Componentsの導入
📌 変更点
- App RouterではデフォルトでServer Componentsが使用される。
- クライアントコンポーネントは
"use client"
を明示的に追加。 getStaticProps
やgetServerSideProps
は使用不可、代わりにサーバーコンポーネント内で直接データ取得。
📝 クライアントコンポーネントの例
// クライアントコンポーネント(ボタン)
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
📝 サーバーコンポーネントでのデータ取得
app/news/page.tsx
// app/news/page.tsx
export default async function NewsPage() {
const res = await fetch('https://api.example.com/news');
const newsList = await res.json();
return (
<main>
{newsList.map(item => <NewsItem key={item.id} data={item} />)}
</main>
);
}
🛠 移行手順
useState
やuseEffect
を使用するコンポーネントに"use client"
を追加。getStaticProps
/getServerSideProps
を削除し、データ取得はサーバーコンポーネント内で行う。
4. 特殊ページの変更
📌 変更点
pages/404.tsx
→app/not-found.tsx
pages/_error.tsx
→app/error.tsx
- ページ読み込み中の処理:
loading.tsx
(各ディレクトリ内に配置可能)
🛠 移行手順
404.tsx
をapp/not-found.tsx
に移行。loading.tsx
を適宜配置してローディング処理を追加。
5. メタデータと<head>の扱い
📌 変更点
<Head>
コンポーネントの代わりにexport const metadata
を使用。head.tsx
で動的なメタタグ設定も可能。
📝 メタデータの設定
app/layout.tsx
// app/layout.tsx
export const metadata = {
title: 'My App',
description: 'This is a Next.js 15 application',
};
🛠 移行手順
- 各ページの
<Head>
の内容をmetadata
に移動。
6. 移行手順まとめ
- Next.jsを最新版(15系)にアップデート
npm install next@latest react@latest react-dom@latest
app/
ディレクトリを作成- Root Layout(
app/layout.tsx
)を実装 - 各ページを
app/
に移動 - データ取得を
fetch
に書き換え - APIルートを
app/api/
へ移動 - クライアントコンポーネントに
"use client"
を追加 - 特殊ページをリネーム
- メタデータを
metadata
に移行 - 不要な
pages/
ディレクトリを削除
まとめ
Next.js 13から15への移行は、App Routerの導入を中心に大きな変更が含まれています。移行の際は、ファイル構成の変更、APIルートの修正、Server Componentsの活用を意識しながら進めるとスムーズです。
Next.js 15の新機能を活かし、より柔軟な開発体験とパフォーマンスの向上を目指しましょう!