こんにちは、かつコーチです。
前回はlayout.tsxの再評価にまつわるつまずきを紹介しましたが、今回は少し毛色の違うエラーを扱います。
App Routerだけを使っているはずなのに、突然Module not found: Can't resolve 'next/router'というエラーが出て困った、という経験はないでしょうか。
このエラーの背景には、Next.js 16でPages Routerが完全に削除されたという事情があります。
前提知識・何が起きるか
このシリーズではApp Routerのみを扱ってきましたが、Next.jsには歴史的にPages Routerという仕組みが存在していました。
Pages Routerはpagesディレクトリを使った旧来のルーティング方式で、next/routerというモジュールからページ遷移用のフックを提供していました。
Next.js 16では、このPages Routerが完全に削除されています。
つまりnext/routerというモジュール自体がNext.js本体から消えているということです。
自分のコードでnext/routerをimportしていなくても、依存しているサードパーティライブラリが内部でnext/routerをimportしていると、次のようなエラーが発生します。
Module not found: Can't resolve 'next/router'
Import trace for requested module:
./node_modules/some-old-library/dist/index.js
自分では一切触っていないコードでエラーが出るため、原因の特定に時間がかかりやすいのが厄介なポイントです。
基本の書き方・実装手順
ステップ1: エラーのImport traceを確認する
まずはエラーメッセージのImport trace for requested moduleの部分を確認します。
ここに表示されているパスが、next/routerをimportしている犯人のライブラリです。
Import trace for requested module:
./node_modules/react-old-modal/dist/hooks/useRouterCompat.js
./node_modules/react-old-modal/dist/index.js
./src/components/Modal.tsx
この例ではreact-old-modalというライブラリが原因だと分かります。
ステップ2: ライブラリのバージョンを確認する
原因のライブラリが特定できたら、そのライブラリの最新バージョンでApp Router対応がされているかを確認します。
npm info react-old-modal versions --json
多くのライブラリは、App Router対応の際にnext/routerへの依存をnext/navigationに置き換えています。
# ❌ Before: App Router未対応の古いバージョンを使い続けている
npm ls react-old-modal
# react-old-modal@2.3.0
# ✅ After: App Router対応済みの最新版に上げる
npm install react-old-modal@latest
ステップ3: 更新版がなければ代替ライブラリへ移行する
ライブラリの開発が止まっていて、App Router対応版が出ていない場合は、代替ライブラリへの移行を検討します。
// ❌ Before: メンテナンスが止まった旧ライブラリ
import { Modal } from "react-old-modal";
export function ConfirmDialog() {
return <Modal title="確認">本当に削除しますか?</Modal>;
}
// ✅ After: App Router対応済みの代替ライブラリに移行
import { Dialog } from "@radix-ui/react-dialog";
export function ConfirmDialog() {
return (
<Dialog.Root>
<Dialog.Trigger>削除</Dialog.Trigger>
<Dialog.Content>
<Dialog.Title>確認</Dialog.Title>
<p>本当に削除しますか?</p>
</Dialog.Content>
</Dialog.Root>
);
}
代替ライブラリを選ぶ際は、READMEに「App Router対応」「Next.js 13以降対応」などの記載があるかを確認すると安心です。
つまずきポイント・一次情報の体験談
私が実際に遭遇した経験を共有します。
社内ツールのNext.jsを16にアップグレードした直後、ビルドが通らなくなりました。
Failed to compile.
./node_modules/legacy-chart-lib/dist/utils/route.js
Module not found: Can't resolve 'next/router'
Import trace for requested module:
./node_modules/legacy-chart-lib/dist/utils/route.js
./node_modules/legacy-chart-lib/dist/index.js
./src/app/dashboard/page.tsx
このプロジェクトはずっと前からApp Routerだけを使っていたので、「pages配下は最初から存在しないのに、なぜnext/routerのエラーが出るのか」と最初は混乱しました。
next/routerは自分で一度もimportしたことがなかったからです。
Import traceをよく読むと、グラフ描画に使っていたlegacy-chart-libというライブラリが原因でした。
このライブラリは内部で「現在のURLパスに応じて表示を切り替える」処理のために、古いnext/routerのAPIを直接importしていたのです。
npm outdatedで確認すると、そのライブラリは1年以上メンテナンスが止まっていました。
最終的には、同等の機能を持つ別のグラフライブラリに乗り換えることで解決しました。
「自分のコードは正しいのに謎のエラーが出る」ときは、node_modules配下の依存ライブラリを疑う、という視点を持っておくと調査が早くなると実感した経験でした。
まとめ
この記事のポイント
- Next.js 16でPages Routerが完全削除されたことで、
next/routerモジュール自体が存在しなくなった - 自分では使っていなくても、依存ライブラリが内部で
next/routerをimportしていればエラーになる - エラーメッセージの
Import traceを読めば、原因のライブラリを特定できる - 対処法は、ライブラリを最新版に更新するか、App Router対応の代替ライブラリに乗り換えるかの2択
- メンテナンスが止まっているライブラリは早めに棚卸ししておくと、将来のアップグレード時の事故を防げる
次に読むべき記事
次回は、Next.jsプロジェクトのディレクトリ構成のベストプラクティスについて、設計の観点から解説します。