公式ドキュメントの和訳を基本にしています。
https://nextjs.org/docs/#routing
Next.jsは各route(レスポンスを返すべきURL)に他のrouteの一覧を配信しているわけではないので、
クライアントサイドのページは他のページについて何も知りません。
スケーラビリティのため、後続のページは全てlazy-loadされます。
以下、Next.jsにおけるページ遷移の方法です。
next/link
を使う
next/link
はNext.jsについてくるルーティング用のコンポーネントです。<a />
をこれでラップすると、クライアントサイドでのページ遷移を起こせます。
ほとんどのサイト内リンクはこれを使うことになるでしょう。
href
とas
を渡す
以下の2つのページについて考えます。
// pages/index.js
import Link from 'next/link'
function Home() {
return (
<div>
詳しくは
<Link href="/about">
<a>こちら</a>
</Link>
をクリックしてください
</div>
)
}
export default Home
// pages/about.js
function About() {
return <p>ほら詳しいでしょう</p>
}
export default About
next/link
は以下のpropsを受け付けます。
-
href
: パス+クエリ文字列。唯一の必須props。 -
as
: 遷移後ブラウザのURLバーに表示されるパス。 -
passHref
: 子コンポーネントにhref
propsを渡すか。デフォルトはfalse。子が<a>
の場合は自動でパスするので、設定不要です。子がオリジナルのコンポーネントの場合(styled-componentsでMyStyledLinkを作っているなど)、trueにすることで href属性が出現し、SEOフレンドリーにできます。 -
prefetch
: バックグラウンドでリンク先をプリフェッチするか。デフォルトはtrue。ただしfalseにしてもhover時にはプリフェッチされます。プリフェッチ機能はプロダクションビルドでのみ機能します。 -
replace
: 遷移時、history
スタックに遷移先URLを追加する代わりに、現在のURLを置換します。デフォルトはfalse。 -
shallow
: データフェッチ(getInitial/getStatic/getServerside props)もページリロードもせずにURLを変えるモード。デフォルトはfalse。該当の/pagesファイルが変わると必ず別ページになるので、クエリを変えるときにしか効果はありません。例えばラーメンの種類を選ぶページで ?ramen_kind=hakata に遷移するなどでしょうか。使ったことがない
function Page() {
const router = useRouter()
useEffect(() => {
// 新ラーメンの表示
}, [router.query.ramen_kind])
return (
<Link href="/ramen?ramen_kind=hakata">
<a>博多ラーメンを選ぶ</a>
</Link>
)
}
-
locale
: 多言語対応時、選択中のlocaleを自動的に先頭につける。デフォルトはtrue。
この、next/link
でのクライアントサイドルーティングは、ブラウザの通常のルーティングと同じように動きます。
- コンポーネントが取得されます
- コンポーネントに
getInitialProps
があれば、データが取得されます。エラーが発生すれば、_error.js
がレンダリングされます。 - 1と2が終わったら、
pushState
が実行され、コンポーネントがレンダリングされます。
URLオブジェクトを渡す
next/link
はURLオブジェクトを渡して使うこともでき、その場合オブジェクトは自動的にURL文字列に変換されます。
import Link from 'next/link'
function Home() {
return (
<div>
アザラシについては
<Link href={{ pathname: '/about', query: { animal: 'seal' } }}>
<a>こちら</a>
</Link>
をクリック
</div>
)
}
export default Home
この場合、URL文字列/about?animal=seal
が生成されます。Node.jsのURLモジュールで定義されているプロパティは何でも利用できます。
next/router
を使う
クライアントサイドの遷移はnext/router
でも実現できます。
クリック以外のトリガー遷移するときや、遷移のロジックがフクザツなときに使えそうです。
router.push(url, as, options)
import { useRouter } from 'next/router'
function ActiveLink({ children, href }) {
const router = useRouter()
const handleClick = (e) => {
e.preventDefault()
router.push(href)
}
return (
<a href={href} onClick={handleClick}>
{children}
</a>
)
}
export default ActiveLink
optionsはnext/linkのpropsと似ています。
- href
: パス+クエリ文字列。
- as
: 遷移後ブラウザのURLバーに表示されるパス。
- options
: next/linkと同じ、shallow
locale