💬

Next.js App Routerにおけるリンクとナビゲーションの基本

2024/11/02に公開

業務でNext.jsに触る機会が多くリンク周りに使える物が多くて混乱したのでドキュメントを読みまとめてみる。

概要

  • Next.jsでリンク遷移やページのナビゲーションをやる方法は以下の四つがある
  1. <Link>コンポーネント: 基本的にはnext/linkのこれを使うのがパフォーマンス良さそう。ドキュメントでも<Link>コンポーネントの使用を推奨している。
  2. useRouter()hook: ルーティングを柔軟に操作したい場合に使用する。クライアントコンポーネント内で使用できる。
  3. redirectfunction
  4. ネイティブのHistory API

<Link>コンポーネントについて

<Link>コンポーネントはHTMLの<a>タグを拡張したもので、hrefプロパティを渡して使用できる。ページが表示される際に自動的にプリフェッチされ、ユーザーのビューポートに入ると事前にリンク先のデータが読み込まれる。

コード例

import Link from 'next/link'
 
export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}

useRouter() hook (Client Components)

クライアントコンポーネント内で、プログラム的にナビゲーションを制御したい場合はuseRouter()フックを使用する。page routerの場合はnext/routerからインポートし、app routerの場合は、next/navigationからインポートする。
ボタンのクリックによるナビゲーションや未ログインユーザを特定のページにリダイレクトしたい時など、<Link>コンポーネントでは足りない時に使用する。

コード例

'use client'
 
import { useRouter } from 'next/navigation'
 
export default function Page() {
  const router = useRouter()
 
  return (
    <button type="button" onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  )
}

redirect function (Server Components)

サーバーコンポーネント内でのリダイレクトにはredirect関数を使用する。絶対URLも使えるため、外部リンクへのリダイレクトにも使用できる。デフォルトではステータスコード 307を返す。また、redirectは内部的にエラーをスローするため、try/catchブロックの外で呼び出す必要がある。

コード例

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')
  }
 
  // ...
}

native History API

  • Next.jsはネイティブのHistory APIwindow.history.pushStatewindow.history.replaceStateを使える。上記の<Link>useRouterでは対応できない場合に使用。

参考文献

https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating

Discussion