【Next.js + Chakra UI】どちらのLinkを使えばいいの?
はじめに
Next.js + ChakraUI でアプリを実装している時に、「どちらのLinkを使えばいいの?」と疑問に思ったので調べつつ実装について考えてみました。
それぞれのLinkについて
NextLink
Client-side transitions between routes can be enabled via the Link component exported by next/link.
Next.jsにはページの概念に基づいたファイルシステムのルーターがデフォルトで存在するので、NextLinkを利用することでクライアント側での遷移が可能
ChakraUILink
Links are accessible elements used primarily for navigation. This component is styled to resemble a hyperlink and semantically renders an <a>.
一方、ChakraUILinkではaタグに似た挙動となる
比較
それぞれのLinkを単体で用いた場合の挙動を比較してみます。
ブラウザの検証ツールで背景に色をつけて比較してみるとChakraUIのLinkのみを用いた場合、画面が一度リロードされるのに対し、Next.jsのLinkを用いた場合は画面をロードすることなく遷移することができました。
NextLink
ChakraUILink
結局どちらのLinkを使うのがいいの?
挙動をみてもわかるようにNextLinkを使うのが好ましいです。しかし、ChakraUIのスタイルの恩恵を受けたいというのも本音です。
ChakraUIのスタイルを使いつつNextLinkで遷移できるような実装がベストなのではと考えられそうです。
実装
NextLinkでChakraUIを囲うことで、画面遷移の責務はNextLinkで担いスタイルはChakraUIを用いることができました。また、passHrefやasでaタグを付与することでSEO的にも問題なく実装することができます。
作成したコンポーネント
import React from 'react';
import NextLink from 'next/link'
type SampleLinkProps = {
children: React.ReactNode
href: string
}
export const SampleLink = ({children, href}: SampleLinkProps) => {
return (
<NextLink href={href} passHref>
{children}
</NextLink>
)
}
ChakraUIのLinkを使用した場合
import { SampleLink } from '@components'
import { Link as ChakraUILink } from '@chakra-ui/react'
<SampleLink href={'/sample'}>
<ChakraUILink>to SamplePage</ChakraUILink>
</SampleLink>
ChakraUIのLink以外の要素を使用した場合
import { SampleLink } from '@components'
import { Link as ChakraUIButton } from '@chakra-ui/react'
<SampleLink href={'/sample'}>
<ChakraUIButton as={'a'}>to SamplePage</ChakraUIButton>
</SampleLink>
追記
NextLinkをコンポーポーネン化すると若干わかりづらくなってしまうため、コンポーネント化しないパータンを追記
ChakraUIのLinkを使用した場合(ChakraUIドキュメント)
import NextLink from 'next/link'
import { Link as ChakraUILink } from '@chakra-ui/react'
<NextLink href={'/sample'} passHref>
<ChakraUILink>to SamplePage</ChakraUILink>
</NextLink>
ChakraUIのLink以外の要素を使用した場合
import NextLink from 'next/link'
import { Button as ChakraUIButton } from '@chakra-ui/react'
<NextLink href={'/sample'}>
<ChakraUIButton as={'a'}>to SamplePage</ChakraUIButton>
</NextLink>
試して微妙だった方法
as props を使用してChakraUILinkにNextLinkの挙動をさせる
NextLinkの要素を割り当ててChakraUIのスタイルを保持しつつNextLinkの挙動を期待していたのですが、下記の実装ではスタイルをうまく当てることができなくなってしまいました。
import NextLink from 'next/link'
import { Link as ChakraUILink, LinkProps as ChakraUILinkProps } from '@chakra-ui/react'
export const SampleLink = (props: ChakraUILinkProps) => {
return (
<ChakraUILink as={NextLink} {...props} />
)
}
まとめ
UIコンポーネントを使ってると「あれ、これどうしたらいいの?」という場面に遭遇することも多々。いろんな方法を模索するのも楽しいものです!
Discussion
Chakra UIのドキュメントに、Next.jsのLinkのことも書いてありました!
Chakra UIの
Link
をNextLink
でラップして、passHref
を渡すだけでいいようです!コメントありがとうございます!URLを追記に含ませていただきました😁
初めまして。
Next.js 13からの仕様変更に伴い、異なる方法でChakraUIのLinkをNextLinkのように扱えるようです。
参照: https://chakra-ui.com/docs/components/link#usage-with-nextjs