リンクとナビゲーション
Next.jsでルート間をナビゲートする方法は4つあります。
<Link>
コンポーネントを使用するuseRouter
フックを使用する (クライアントコンポーネント)redirect
関数を使用する (サーバーコンポーネント)- ネイティブのHistory APIを使用する
このページでは、これらの各オプションの使用方法を説明し、ナビゲーションの仕組みについて詳しく解説します。
<Link>
コンポーネント
<Link>
は、HTMLの<a>
タグを拡張してプリフェッチとルート間のクライアントサイドナビゲーションを提供する組み込みコンポーネントです。これは、Next.jsでルート間をナビゲートするための主要かつ推奨される方法です。
next/link
からインポートし、コンポーネントにhref
プロップを渡すことで使用できます。
import Link from 'next/link'
export default function Page() {
return <Link href="/dashboard">Dashboard</Link>
}
<Link>
に渡すことができる他のオプションのプロップがあります。詳しくは、APIリファレンスを参照してください。
useRouter()
フック
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>
)
}
useRouter
メソッドの完全なリストについては、APIリファレンスを参照してください。
推奨事項:
useRouter
を使用する特定の要件がない限り、ルート間をナビゲートするには<Link>
コンポーネントを使用してください。
redirect
関数
サーバーコンポーネントの場合は、代わりにredirect
関数を使用します。
import { redirect } from 'next/navigation'
async function fetchTeam(id: string) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }: { params: { id: string } }) {
const team = await fetchTeam(params.id)
if (!team) {
redirect('/login')
}
// ...
}
知っておくと良いこと:
redirect
は、デフォルトで307 (Temporary Redirect) ステータスコードを返します。サーバーアクションで使用すると、POSTリクエストの結果として成功ページにリダイレクトするためによく使用される303 (See Other) を返します。redirect
は内部的にエラーをスローするため、try/catch
ブロックの外で呼び出す必要があります。redirect
は、レンダリングプロセス中にクライアントコンポーネントで呼び出すことができますが、イベントハンドラーでは呼び出すことはできません。代わりにuseRouter
フックを使用できます。redirect
は絶対URLも受け入れ、外部リンクにリダイレクトするためにも使用できます。- レンダリングプロセスの前にリダイレクトしたい場合は、
next.config.js
またはミドルウェアを使用してください。
詳細については、redirect
APIリファレンスを参照してください。
ネイティブHistory APIの使用
Next.jsでは、ネイティブのwindow.history.pushState
とwindow.history.replaceState
メソッドを使用して、ページをリロードせずにブラウザの履歴スタックを更新できます。
pushState
とreplaceState
の呼び出しは、Next.jsルーターに統合されており、usePathname
およびuseSearchParams
と同期できます。
window.history.pushState
これを使用して、ブラウザの履歴スタックに新しいエントリを追加します。ユーザーは前の状態に戻ることができます。たとえば、製品リストをソートする場合に使用します。
'use client'
import { useSearchParams } from 'next/navigation'
export default function SortProducts() {
const searchParams = useSearchParams()
function updateSorting(sortOrder: string) {
const params = new URLSearchParams(searchParams.toString())
params.set('sort', sortOrder)
window.history.pushState(null, '', `?${params.toString()}`)
}
return (
<>
<button onClick={() => updateSorting('asc')}>Sort Ascending</button>
<button onClick={() => updateSorting('desc')}>Sort Descending</button>
</>
)
}
window.history.replaceState
これを使用して、ブラウザの履歴スタックの現在のエントリを置き換えます。ユーザーは前の状態に戻ることができません。たとえば、アプリケーションのロケールを切り替える場合に使用します。
'use client'
import { usePathname } from 'next/navigation'
export function LocaleSwitcher() {
const pathname = usePathname()
function switchLocale(locale: string) {
// e.g. '/en/about' or '/fr/contact'
const newPath = `/${locale}${pathname}`
window.history.replaceState(null, '', newPath)
}
return (
<>
<button onClick={() => switchLocale('en')}>English</button>
<button onClick={() => switchLocale('fr')}>French</button>
</>
)
}
ルーティングとナビゲーションの仕組み
App Routerは、ルーティングとナビゲーションにハイブリッドアプローチを使用しています。サーバー側では、アプリケーションコードはルートセグメントごとに自動的にコード分割されます。クライアント側では、Next.jsがルートセグメントをプリフェッチおよびキャッシュします。つまり、ユーザーが新しいルートに移動する場合、ブラウザはページをリロードせず、変更されたルートセグメントのみが再レンダリングされるため、ナビゲーションエクスペリエンスとパフォーマンスが向上します。
1. コード分割
コード分割を使用すると、アプリケーションコードをより小さなバンドルに分割し、ブラウザでダウンロードして実行することができます。これにより、各リクエストで転送されるデータ量と実行時間が減少し、パフォーマンスが向上します。
サーバーコンポーネントを使用すると、アプリケーションコードをルートセグメントごとに自動的にコード分割できます。つまり、現在のルートに必要なコードのみがナビゲーション時にロードされます。
2. プリフェッチ
プリフェッチは、ユーザーがアクセスする前にバックグラウンドでルートをプリロードする方法です。
Next.jsでは、2つの方法でルートがプリフェッチされます。
<Link>
コンポーネント: ルートは、ユーザーのビューポートに表示されると自動的にプリフェッチされます。プリフェッチは、ページが最初にロードされたとき、またはスクロールを通じて表示されたときに発生します。router.prefetch()
:useRouter
フックを使用して、プログラムでルートをプリフェッチできます。
<Link>
のデフォルトのプリフェッチ動作(つまり、prefetch
プロップが指定されていないか、null
に設定されている場合)は、loading.js
の使用状況によって異なります。最初のloading.js
ファイルまでの、レンダリングされたコンポーネントの「ツリー」を下にたどる共有レイアウトのみがプリフェッチされ、30秒
間キャッシュされます。これにより、動的ルート全体をフェッチするコストが削減され、ユーザーにより良い視覚的なフィードバックを提供するために、即時ロード状態を表示できます。
prefetch
プロップをfalse
に設定すると、プリフェッチを無効にできます。または、prefetch
プロップをtrue
に設定すると、ロード境界を超えたページ全体データをプリフェッチできます。
詳細については、<Link>
APIリファレンスを参照してください。
知っておくと良いこと:
- プリフェッチは開発環境では有効になっておらず、本番環境でのみ有効になっています。
3. キャッシュ
Next.jsには、ルーターキャッシュと呼ばれるインメモリクライアント側キャッシュがあります。ユーザーがアプリ内を移動すると、プリフェッチされたルートセグメントと訪問済みのルートのReactサーバーコンポーネントペイロードがキャッシュに保存されます。
つまり、ナビゲーション時に、サーバーへの新しいリクエストを行う代わりに、キャッシュが可能な限り再利用されます。これにより、リクエスト数と転送されるデータ量を減らすことでパフォーマンスが向上します。
ルーターキャッシュの仕組みと構成方法の詳細をご覧ください。
4. 部分レンダリング
部分レンダリングとは、ナビゲーション時に変更されたルートセグメントのみがクライアントで再レンダリングされ、共有セグメントは保持されることを意味します。
たとえば、2つの兄弟ルート、/dashboard/settings
と/dashboard/analytics
の間を移動する場合、settings
ページはアンマウントされ、analytics
ページは新しい状態でマウントされ、共有のdashboard
レイアウトは保持されます。この動作は、/blog/[slug]/page
のように同じ動的セグメント上の2つのルート間でも発生し、/blog/first
から/blog/second
に移動する場合も同様です。


部分レンダリングがない場合、各ナビゲーションでページ全体がクライアントで再レンダリングされます。変更されたセグメントのみをレンダリングすることで、転送されるデータ量と実行時間が減少し、パフォーマンスが向上します。
5. ソフトナビゲーション
ブラウザは、ページ間を移動する際に「ハードナビゲーション」を実行します。Next.js App Routerは、ページ間の「ソフトナビゲーション」を有効にし、変更されたルートセグメントのみが再レンダリングされるようにします(部分レンダリング)。これにより、ナビゲーション中にクライアントのReactの状態を保持できます。
6. 戻るおよび進むナビゲーション
デフォルトでは、Next.jsは、戻るおよび進むナビゲーションのスクロール位置を維持し、ルーターキャッシュのルートセグメントを再利用します。
7. pages/
とapp/
間のルーティング
pages/
から app/
へと段階的に移行する場合、Next.js のルーターは両者間のハードナビゲーションを自動的に処理します。pages/
から app/
への遷移を検出するために、クライアントルーターフィルターが使用され、これはアプリルートの確率的チェックを利用しています。そのため、まれに誤検出が発生する可能性があります。デフォルトでは、誤検出の可能性は 0.01% に設定されているため、このような発生は非常にまれであるはずです。この可能性は、next.config.js
の experimental.clientRouterFilterAllowedRate
オプションを使用してカスタマイズできます。誤検出率を下げると、クライアントバンドルで生成されるフィルターのサイズが増加することに注意が必要です。
あるいは、この処理を完全に無効にして、pages/
と app/
の間のルーティングを手動で管理したい場合は、next.config.js
で experimental.clientRouterFilter
を false に設定できます。この機能を無効にすると、pages/
内の動的ルートで app/
ルートと重複するものがある場合、デフォルトでは適切にナビゲートされません。
次のステップ
この記事は役に立ちましたか?