useRouter

useRouter フックを使用すると、クライアントコンポーネント内でプログラム的にルートを変更できます。

推奨事項: 特に理由がない限り、ナビゲーションには <Link> コンポーネントを使用し、useRouter の使用は特定の要件がある場合に限定してください。

'use client'

import { useRouter } from 'next/navigation'

export default function Page() {
  const router = useRouter()

  return (
    <button type="button" onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  )
}
'use client'

import { useRouter } from 'next/navigation'

export default function Page() {
  const router = useRouter()

  return (
    <button type="button" onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  )
}

useRouter()

  • router.push(href: string, { scroll: boolean }): 指定されたルートへクライアントサイドナビゲーションを実行します。ブラウザの履歴スタックに新しいエントリを追加します。
  • router.replace(href: string, { scroll: boolean }): 指定されたルートへクライアントサイドナビゲーションを実行しますが、ブラウザの履歴スタックには新しいエントリを追加しません。
  • router.refresh(): 現在のルートを更新します。サーバーに新しいリクエストを送信し、データリクエストを再取得してサーバーコンポーネントを再レンダリングします。クライアントは影響を受けないクライアントサイドのReact状態(例: useState)やブラウザ状態(例: スクロール位置)を保持したまま、更新されたReactサーバーコンポーネントのペイロードをマージします。
  • router.prefetch(href: string): クライアントサイド遷移を高速化するため、指定されたルートをプリフェッチします。
  • router.back(): ブラウザの履歴スタックで前のルートに戻ります。
  • router.forward(): ブラウザの履歴スタックで次のページに進みます。

知っておくと便利:

  • 信頼できないまたはサニタイズされていないURLを router.pushrouter.replace に送信しないでください。これはクロスサイトスクリプティング(XSS)脆弱性を引き起こす可能性があります。例えば、javascript: URLを router.pushrouter.replace に送信すると、ページのコンテキストで実行されます。
  • <Link> コンポーネントは、ビューポート内で表示されたルートを自動的にプリフェッチします。
  • フェッチリクエストがキャッシュされている場合、refresh() は同じ結果を再生成する可能性があります。cookiesheaders などの他の動的APIもレスポンスを変更する可能性があります。

next/router からの移行

  • App Router を使用する場合、useRouter フックは next/router ではなく next/navigation からインポートする必要があります
  • pathname 文字列は削除され、usePathname() に置き換えられました
  • query オブジェクトは削除され、useSearchParams() に置き換えられました
  • router.events は置き換えられました。下記を参照

完全な移行ガイドを確認

使用例

ルーターイベント

usePathnameuseSearchParams などの他のクライアントコンポーネントフックを組み合わせることで、ページ変更を監視できます。

app/components/navigation-events.js
'use client'

import { useEffect } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'

export function NavigationEvents() {
  const pathname = usePathname()
  const searchParams = useSearchParams()

  useEffect(() => {
    const url = `${pathname}?${searchParams}`
    console.log(url)
    // 現在のURLを使用できます
    // ...
  }, [pathname, searchParams])

  return '...'
}

これをレイアウトにインポートできます。

app/layout.js
import { Suspense } from 'react'
import { NavigationEvents } from './components/navigation-events'

export default function Layout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}

        <Suspense fallback={null}>
          <NavigationEvents />
        </Suspense>
      </body>
    </html>
  )
}

知っておくと便利: useSearchParams()静的レンダリング中に、最も近いSuspense バウンダリまでクライアントサイドレンダリングを引き起こすため、<NavigationEvents>Suspense バウンダリでラップされています。詳細を確認

トップへのスクロールを無効化

デフォルトでは、Next.jsは新しいルートにナビゲートする際にページのトップにスクロールします。この動作を無効にするには、router.push()router.replace()scroll: false を渡します。

'use client'

import { useRouter } from 'next/navigation'

export default function Page() {
  const router = useRouter()

  return (
    <button
      type="button"
      onClick={() => router.push('/dashboard', { scroll: false })}
    >
      Dashboard
    </button>
  )
}
'use client'

import { useRouter } from 'next/navigation'

export default function Page() {
  const router = useRouter()

  return (
    <button
      type="button"
      onClick={() => router.push('/dashboard', { scroll: false })}
    >
      Dashboard
    </button>
  )
}

バージョン履歴

バージョン変更点
v13.0.0next/navigation からの useRouter が導入されました。