
【実践】Next.js 13→16メジャーアップグレードの全記録 — 破壊的変更と対応策
[toc]
はじめに
-
Next.js 13から16への3世代スキップアップグレードを実施した
-
背景: Cloudflare Workers移行に伴い、OpenNextが要求するNext.js 15以上への対応が必要になった
-
段階的にやるか一気にやるか検討した結果、一気にアップグレードする方針を選択
-
各バージョンの破壊的変更を事前に洗い出し、計画的に対応した
この記事でわかること
-
Next.js 14: params型のPromise化への対応方法
-
Next.js 15: useSearchParamsのSuspense境界必須化への対応
-
Next.js 16: Turbopack標準化によるビルド速度向上
-
React 18→19の型定義更新(@types/react@19)
対象読者
-
Next.jsのメジャーアップグレードを予定している方
-
Next.js 13以前のプロジェクトを最新版に追従させたい方
-
破壊的変更の影響範囲を事前に把握したい方
1. Next.js 14: params型がPromiseに変更
変更内容
Next.js 14以降、動的ルートのparamsがPromiseを返すように変更された。これはApp Routerの非同期レンダリング最適化の一環。
Before(Next.js 13)
// src/app/blogs/[blogId]/page.tsx
export default function BlogDetail({ params }: { params: { blogId: string } }) {
const { blogId } = params; // 同期的にアクセス可能
// ...
}
After(Next.js 14+)
// src/app/blogs/[blogId]/page.tsx
export default async function BlogDetail({ params }: { params: Promise<{ blogId: string }> }) {
const { blogId } = await params; // awaitが必須
// ...
}
影響範囲
-
[blogId]/page.tsx— ブログ詳細ページ -
[categoryId]/page.tsx— カテゴリ別一覧ページ -
[tagId]/page.tsx— タグ別一覧ページ -
page/[pageId]/page.tsx— ページネーション -
generateMetadata関数のparams引数も同様に変更
対応のポイント
// generateMetadataも同様にawaitが必要
export async function generateMetadata({ params }: { params: Promise<{ blogId: string }> }) {
const { blogId } = await params;
const blog = await getDetail(blogId);
return { title: blog.title };
}
2. Next.js 15: useSearchParamsにSuspense境界必須
変更内容
Next.js 15では、useSearchParams()を使用するコンポーネントを<Suspense>で囲むことが必須になった。囲まないとビルドエラーが発生する。
問題が発生したコンポーネント
Google Analyticsのページビュー追跡でuseSearchParamsを使用していたため、ビルドが失敗した。
Before
// libs/gtag.ts のPageviewコンポーネント
'use client';
import { useSearchParams } from 'next/navigation';
export function GoogleAnalytics() {
const searchParams = useSearchParams(); // Suspenseなしで使用
// ...
}
After
// layout.tsx
import { Suspense } from 'react';
import { GoogleAnalytics } from '@/libs/gtag';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Suspense fallback={null}>
<GoogleAnalytics />
</Suspense>
{children}
</body>
</html>
);
}
検索ページでの対応
検索フォームコンポーネントも同様にSuspenseで囲む必要があった。
<Suspense fallback={<SearchFormSkeleton />}>
<SearchForm />
</Suspense>
3. Next.js 16: Turbopack標準化
変更内容
Next.js 16ではTurbopackがデフォルトのバンドラーとして標準化された。
ビルド速度の改善
| 指標 | webpack(Next.js 13) | Turbopack(Next.js 16) |
|---|---|---|
| dev起動 | 約3.5秒 | 約1.2秒 |
| HMR | 約800ms | 約200ms |
| プロダクションビルド | 約45秒 | 約30秒 |
注意点
-
next.config.jsのwebpack設定はTurbopackでは無視される -
カスタムwebpackプラグインを使用している場合は移行が必要
-
今回のプロジェクトではwebpackのカスタム設定がなかったため影響なし
4. React 18→19の変更点
型定義の更新
React 19では型定義が大幅に変更された。@types/react@19への更新が必要。
npm install @types/react@19 @types/react-dom@19
主な型の変更
// React.FC の children が暗黙的に含まれなくなった
// Before
const Component: React.FC = ({ children }) => { ... };
// After - 明示的にchildrenを定義
const Component: React.FC<{ children: React.ReactNode }> = ({ children }) => { ... };
useRef の変更
// Before: initialValueがnullでもOK
const ref = useRef<HTMLDivElement>(null);
// After: React 19では RefObject の型が変更
// null初期値の場合は MutableRefObject ではなく RefObject を返す
const ref = useRef<HTMLDivElement>(null);
// 型は RefObject<HTMLDivElement | null> になる
Tips
npx @next/codemod@latest upgrade を使うと、破壊的変更の一部を自動で修正してくれるstrictモードを有効にしておくと、params型の変更を確実に検出できるnpm outdatedで全依存関係の状態を確認し、Next.jsと相性の悪いパッケージを事前に特定しておくまとめ
-
Next.js 13→16の3世代スキップアップグレードは計画的に行えば十分実用的
-
最大の破壊的変更はparams型のPromise化(Next.js 14)で、全動的ルートの修正が必要
-
useSearchParamsのSuspense必須化(Next.js 15)はGoogle Analytics等の共通コンポーネントに影響
-
Turbopack標準化(Next.js 16)は基本的にゼロコストで恩恵を受けられる
-
React 19の型変更は
@types/react@19への更新で対応可能
最新記事
- 【設定・環境構築】OpenNext でNext.js SSGサイトをCloudflare Workersにデプロイする完全ガイド
2026/3/19
- 【実装】Notion calloutブロックをNext.jsでカラフルなUIコンポーネントとして表示する
2026/3/19
- 【トラブルシューティング】Cloudflare Pages → Workers 移行で遭遇したEdge Runtime問題集
2026/3/19
- 【実践】Next.js 13→16メジャーアップグレードの全記録 — 破壊的変更と対応策
2026/3/19
- 【自動化】Gemini Imagen APIでブログのeyecatch画像を自動生成してR2にアップロードする
2026/3/19
- 【実装】Notion APIでブログシステムを構築する(Next.js 13 App Router × SDK v5)
2026/3/19
- 【移行ガイド】microCMSからNotion APIへブログCMSを完全移行する
2026/3/19
- 【トラブルシューティング】本番デプロイで遭遇した問題と解決策まとめ
2026/3/15
- 【環境構築】Next.js × Cloudflare Workers の本番環境を一から構築する
2026/3/15
- 【設定・環境構築】Neon → Prisma Postgres 移行とローカル開発環境の構築
2026/2/26


