先に進む前に、まずはルーティング入門をお読みになることをお勧めします。
ルート間のクライアント側のトランジションは、next/link
でエクスポートされた Link
コンポーネントを介して有効にできます。
例として、以下のファイルを含む pages
ディレクトリを考えてみましょう:
pages/index.js
pages/about.js
pages/blog/[slug].js
以下のようにして、それぞれのページに対してリンクを設定できます:
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link href="/">
<a>Home</a>
</Link>
</li>
<li>
<Link href="/about">
<a>About Us</a>
</Link>
</li>
<li>
<Link href="/blog/hello-world">
<a>Blog Post</a>
</Link>
</li>
</ul>
)
}
export default Home
Link
は以下の props を受け入れます:
href
- 遷移したい先のパスまたは URL です。これは唯一必須のプロパティです。as
- ブラウザの URL バーに表示される、パスのオプショナルなデコレーターです。Next.js 9.5.3 以前は動的ルーティングに使用されていました。以前のバージョンでどのように動作していたかを知りたい場合は過去のドキュメントをご確認ください。備考: このパスが href
で与えられるパスと異なる場合は、以前の href
/as
の挙動になります。詳細は過去のドキュメントに記載があります。passHref
- Link
が子に href
プロパティを強制送信します。デフォルトは false
です。prefetch
- バックグラウンドでページをプリフェッチします。デフォルトは true
です。ビューポート内にある <Link />
はすべてプリロードされます (初期状態やスクロール中)。prefetch={false}
を渡すことでプリフェッチは無効になります。prefetch
が false
に設定されている場合でも、ホバー時にはプリフェッチが行われます。静的生成を使用しているページでは、ページ遷移を高速化するためにデータと一緒に JSON
ファイルがプリロードされます。プリフェッチは本番環境でのみ有効です。replace
- スタックに新しい URL を追加する代わりに、現在の history
の state を置き換えます。デフォルトは false
です。scroll
- ナビゲーションの後にページの先頭にスクロールします。デフォルトは true
です。shallow
- getStaticProps
、 getServerSideProps
、 getInitialProps
を再実行せずに現在のページのパスを更新します。デフォルトは false
です。locale
- アクティブなロケールが自動的に先頭に追加されます。locale
を設定することで異なるロケールを指定できます。false
の場合は、デフォルトの動作が無効であるため href
にロケールを含める必要があります。Next.js 9.5.3 以降では(古いバージョンについては過去のドキュメントをご確認ください)、何もせずとも動的ルーティング(すべてのルートを受け取る場合を含めて)へのリンクを設定できます。しかし、文字列補間 や URL オブジェクトを用いてリンクを生成することが非常に一般的で便利な状況も存在します。
たとえば、 pages/blog/[slug].js
という動的ルーティングは以下のリンクにマッチします:
import Link from 'next/link'
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${encodeURIComponent(post.slug)}`}>
<a>{post.title}</a>
</Link>
</li>
))}
</ul>
)
}
export default Posts
<a>
タグをラップするカスタムコンポーネントの場合Link
の子が <a>
タグをラップするカスタムコンポーネントの場合は、Link
に passHref
を追加する必要があります。これは styled-components のようなライブラリを使用している場合は必要です。これがないと、<a>
タグには href
属性が付与されず、サイトのアクセシビリティを損ない、SEO に悪影響を及ぼす可能性があります。ESLint を使っている場合は、passHref
の正しく使用するための next/link-passhref
という組み込みのルールがあります。
import Link from 'next/link'
import styled from 'styled-components'
// これは、<a> タグをラップするカスタムコンポーネントを作成します
const RedLink = styled.a`
color: red;
`
function NavLink({ href, name }) {
// リンクに passHref を追加する必要があります
return (
<Link href={href} passHref>
<RedLink>{name}</RedLink>
</Link>
)
}
export default NavLink
@jsx jsx
)を使用している場合は、<a>
タグを直接使用していても passHref
を使用しなければなりません。onClick
属性をサポートする必要があります。Link
の子が関数コンポーネントの場合、passHref
の使用に加えて、React.forwardRef
でコンポーネントをラップする必要があります:
import Link from 'next/link'
// `onClick`, `href`, `ref` を適切に処理するためには
// DOM 要素に渡す必要があります
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
return (
<a href={href} onClick={onClick} ref={ref}>
Click Me
</a>
)
})
function Home() {
return (
<Link href="/about" passHref>
<MyButton />
</Link>
)
}
export default Home
Link
は URL オブジェクトを受け取ることもでき、それを自動的にフォーマットして URL 文字列を作成してくれます。その方法は以下の通りです:
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
<a>About us</a>
</Link>
</li>
<li>
<Link
href={{
pathname: '/blog/[slug]',
query: { slug: 'my-post' },
}}
>
<a>Blog Post</a>
</Link>
</li>
</ul>
)
}
export default Home
上記の例には以下へのリンクが含まれています:
/about?name=test
/blog/my-post
Node.js の URL モジュールのドキュメントで定義されているすべてのプロパティを使用できます。
Link
コンポーネントのデフォルトの挙動は、新しい URL を history
スタックに push
することです。以下の例のように、replace
prop を使って新しいエントリを追加しないようにできます:
<Link href="/about" replace>
<a>About us</a>
</Link>
Link
のデフォルトの挙動はページの先頭までスクロールします。ハッシュが定義されている場合は、通常の <a>
タグのように特定の id にスクロールします。ページのトップ / ハッシュへのスクロールを防ぐために、Link
に scroll={false}
を追加できます:
<Link href="/?counter=10" scroll={false}>
<a>Disables scrolling to the top</a>
</Link>