NextRouter was not mounted の直し方
実際に出るエラー
App Router のページで next/router の useRouter を使ったときに出るエラーです。
何が起きているか
useRouter は2つあります。import 元が違うだけで、名前は同じです。
| import 元 | 使える場所 |
|---|---|
| next/router | Pages Router(pages/)だけ |
| next/navigation | App Router(app/) |
App Router のページで next/router の方を使うと、そのルーターは用意されていません。実機で確かめたところ、どこで使ったかで文言が変わりました。
| 使った場所 | 文言 |
|---|---|
| use client の部品 | NextRouter was not mounted. |
| use client の無いページ | You have a Server Component that imports next/router. Use next/navigation instead. |
どちらもビルドの段階で止まります。Pages Router で書いた部品を持ってきたときや、エディタの自動 import が next/router を選んだときに出ます。
直し方
読み込む先を next/navigation に変えます。
'use client'
import { useRouter } from 'next/navigation'
export default function Nav() {
const router = useRouter()
return <button onClick={() => router.push('/b')}>go</button>
}
push・replace・back・refresh は、そのまま使えます。
query と pathname は無くなる
import 元だけを変えると、次はここで止まります。
Property 'query' does not exist on type 'AppRouterInstance'.
実機で確かめました。App Router の useRouter が持っているのは、移動のための操作だけです(型定義では back・forward・refresh・push・replace・prefetch)。以前の useRouter が持っていた値は、別の場所に分かれました。
| 以前(next/router) | App Router |
|---|---|
| router.query(クエリ文字列) | useSearchParams().get('id') |
| router.query(動的なパスの値) | ページの params(await して取り出す) |
| router.pathname | usePathname() |
移行するときは、まとめて探す
1つ直すたびにビルドして次のエラーを見る、を繰り返すより、先に全部探す方が早く終わります。
grep -rn "next/router" app/
grep -rn "router.query\|router.pathname\|router.asPath" app/
見つかったものを、上の表に沿って置き換えます。
出典
- nextjs.org/docs/messages/next-router-not-mounted
- nextjs.org/docs/app/api-reference/functions/use-router
- nextjs.org/docs/app/guides/migrating/app-router-migration
このページの内容は上記の一次情報を基準に書いています。個人ブログや二次情報を根拠にしていません。