
Linkコンポーネントによる画面遷移
2025-08-12はじめに
前回までにNext.jsのページコンポーネント作成方法を学びました。今回は、作成したページ間をシームレスに移動するための「Linkコンポーネント」について詳しく解説します。ReactのSPA(シングルページアプリケーション)経験者にとって、Next.jsのナビゲーションはより簡単でパワフルです。
なぜLinkコンポーネントが必要か?
従来のaタグの問題点
通常のHTMLではページ遷移に<a>
タグを使用しますが、これには以下の問題があります:
- ページ全体のリロードが発生し、パフォーマンスが低下
- アプリケーション状態がリセットされてしまう
- スムーズな遷移ができない
Linkコンポーネントのメリット
Next.jsのLink
コンポーネントを使用すると:
- クライアントサイドナビゲーション(ページ全体のリロードなし)
- アプリ状態の保持(Reactの状態が維持される)
- 自動的なプリフェッチ(viewport内のリンクを自動で先読み)
- 高速なページ遷移
Linkコンポーネントの基本使用法
1. 基本的なインポートと使用
まず、next/link
からLinkコンポーネントをインポートします:
import Link from 'next/link';
function Navigation() {
return (
<nav>
<Link href="/">ホーム</Link>
<Link href="/about">About</Link>
<Link href="/products">製品情報</Link>
</nav>
);
}
2. スタイルを適用する場合
Linkコンポーネント自体にスタイルは適用できないので、子要素を追加します:
<Link href="/about">
<a className="nav-link">Aboutページ</a>
</Link>
// Next.js v13以降では以下のように記述
<Link href="/about" className="nav-link">
Aboutページ
</Link>
3. ボタンとして使用
<Link href="/contact">
<button className="btn btn-primary">お問い合わせ</button>
</Link>
Linkコンポーネントの詳細な使い方
1. 動的ルートへのリンク
動的ルート([id].jsや[slug].jsなど)にリンクする場合:
<Link href={`/blog/${post.slug}`}>
<a>{post.title}</a>
</Link>
// またはオブジェクト形式で
<Link href={{
pathname: '/blog/[slug]',
query: { slug: post.slug }
}}>
<a>{post.title}</a>
</Link>
2. URLクエリパラメータの使用
クエリパラメータを付与する場合:
<Link href={{
pathname: '/search',
query: { keyword: 'nextjs' }
}}>
<a>Next.jsで検索</a>
</Link>
3. リンクの挙動をカスタマイズ
replace
やscroll
プロパティで挙動を変更:
<Link href="/" replace scroll={false}>
<a>ホームに戻る(履歴に残さない、スクロール位置をリセットしない)</a>
</Link>
replace
: trueにすると、ブラウザの履歴に現在のページを残さないscroll
: falseにすると、ページ遷移後トップにスクロールしない
アクティブなリンクのスタイリング
現在のページに対応するリンクにスタイルを適用するには、useRouter
フックを使用します:
import { useRouter } from 'next/router';
import Link from 'next/link';
function NavItem({ href, children }) {
const router = useRouter();
const isActive = router.pathname === href;
return (
<Link href={href}>
<a className={isActive ? 'active' : ''}>
{children}
</a>
</Link>
);
}
// 使用例
<NavItem href="/">ホーム</NavItem>
<NavItem href="/about">About</NavItem>
Linkコンポーネントの高度な機能
1. プリフェッチの制御
Next.jsはデフォルトでviewport内のLinkを自動プリフェッチしますが、無効化も可能:
<Link href="/about" prefetch={false}>
<a>About(プリフェッチしない)</a>
</Link>
2. プログラムによるナビゲーション
useRouter
フックでプログラム的にページ遷移:
import { useRouter } from 'next/router';
function LoginButton() {
const router = useRouter();
const handleLogin = () => {
// ログイン処理後にダッシュボードへ遷移
router.push('/dashboard');
};
return (
<button onClick={handleLogin}>
ログイン
</button>
);
}
3. 遷移イベントの監視
ページ遷移の開始と完了を監視:
import { useEffect } from 'react';
import { useRouter } from 'next/router';
function PageProgress() {
const router = useRouter();
useEffect(() => {
const handleStart = (url) => {
console.log(`Loading: ${url}`);
// プログレスバーを表示など
};
const handleComplete = (url) => {
console.log(`Loaded: ${url}`);
// プログレスバーを非表示など
};
router.events.on('routeChangeStart', handleStart);
router.events.on('routeChangeComplete', handleComplete);
return () => {
router.events.off('routeChangeStart', handleStart);
router.events.off('routeChangeComplete', handleComplete);
};
}, []);
return null;
}
よくある間違いとベストプラクティス
避けるべきパターン
- aタグを直接使用しない:
// 悪い例(ページ全体がリロードされる)
<a href="/about">About</a>
// 良い例
<Link href="/about"><a>About</a></Link>
- イベントハンドラをLinkに直接追加しない:
// 悪い例
<Link href="/about" onClick={handleClick}>
<a>About</a>
</Link>
// 良い例
<Link href="/about">
<a onClick={handleClick}>About</a>
</Link>
ベストプラクティス
- 一貫したリンクスタイル:
- アプリ全体でリンクのスタイルを統一
- hoverやfocus状態も考慮
- アクセシビリティの確保:
<Link href="/about">
<a aria-current={router.pathname === '/about' ? 'page' : undefined}>
About
</a>
</Link>
- 重要なナビゲーションはプリフェッチ:
- 主要なナビゲーションリンクは
prefetch={true}
(デフォルト)を維持 - 使用頻度の低いリンクは
prefetch={false}
実際の使用例
ナビゲーションバーの実装
import Link from 'next/link';
import { useRouter } from 'next/router';
export default function Navbar() {
const router = useRouter();
return (
<nav className="navbar">
<div className="logo">
<Link href="/">
<a>MyApp</a>
</Link>
</div>
<div className="links">
<Link href="/">
<a className={router.pathname === '/' ? 'active' : ''}>ホーム</a>
</Link>
<Link href="/about">
<a className={router.pathname === '/about' ? 'active' : ''}>About</a>
</Link>
<Link href="/products">
<a className={router.pathname === '/products' ? 'active' : ''}>製品</a>
</Link>
<Link href="/contact">
<a className={router.pathname === '/contact' ? 'active' : ''}>お問い合わせ</a>
</Link>
</div>
</nav>
);
}
ブログ記事一覧の実装
import Link from 'next/link';
export default function PostList({ posts }) {
return (
<div className="post-list">
{posts.map((post) => (
<article key={post.id} className="post-card">
<Link href={`/blog/${post.slug}`}>
<a>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
<time dateTime={post.date}>{post.date}</time>
</a>
</Link>
</article>
))}
</div>
);
}
まとめ
Next.jsのLink
コンポーネントは、SPAのようなスムーズなユーザー体験を簡単に実現する強力なツールです。主なポイントは:
- 従来の
<a>
タグの代わりにLink
を使用することでクライアントサイドナビゲーションを実現 - 動的ルートやクエリパラメータにも簡単に対応
- プリフェッチ機能でパフォーマンスを最適化
useRouter
でプログラム的なナビゲーションや状態管理が可能
Next.jsのルーティングシステムを活用すれば、ユーザー体験が向上し、SEOにも有利なアプリケーションを構築できます。次回は、Next.jsの重要な機能である「静的生成(SSG)」について詳しく解説します。
さらに深く学びたい方は、Next.js公式ドキュメントも参照してください:
https://nextjs.org/docs/api-reference/next/link