Zennみたいな目次を作りたい!
はじめに
現在ブログサイトを作成しており、ZennやQiitaのような目次機能を追加したいと考えています。
色々調べてみたところ、Tocbotが使いやすそうだったので、これを使ってみることにしました!
Tocbotとは
Tocbotは、htmlの見出しタグから目次を自動的に作成してくれるライブラリです。
目次をクリックすればhtmlの該当箇所まで自動でスクロールしてくれたり、見た目も自分好みにカスタマイズすることができます。
使い方
以下は基本的なtocbotの導入方法になります!
前提条件(技術スタック)
- フロントエンド: Next.js, TypeScript, Tailwind CSS
- バックエンド : MicroCMS
tocbotをインストール
以下のコマンドで、プロジェクトにTocbotをインストールします
npm install --save tocbot
目次用のコンポーネントを作成
'use client'
import { useEffect } from 'react'
import tocbot from 'tocbot'
const TableOfContentsSideBar = () => {
useEffect(() => {
tocbot.init({
// 目次を表示させる先のクラス名
tocSelector: '.js-toc',
// 目次を抽出したい要素のクラス名
contentSelector: '.js-toc-content',
// 目次として抽出する見出しタグ
headingSelector: 'h1, h2, h3, h4'
})
// 不要になったインスタンスを削除
return () => tocbot.destroy()
}, [])
return <nav className="js-toc" />
}
export default TableOfContentsSideBar
まずuseEffect内で、tocbot.init(options)
をしてtocbotを初期化します。
optionsではさまざまなカスタマイズができるので、ぜひ公式ドキュメントを見てみてください。
実際に以下のようなブログ記事ページができました。
画像の右端にあるのか、今回追加した目次コンポーネントです。
まだスタイルは何も変更していないので、今のところ目次を取得して表示されているだけです。
ここからは実際にスタイルも変更していこうと思います。
スタイルの変更
Tocbotのスタイルを変更するには、CDNを読み込ませるか、独自で定義するかになります。
CDNで読み込ませる場合は、先ほどの目次表示用のコンポーネントを以下のように変更します。
このとき、next/head
のHeadタグを使っています。
return (
<>
<Head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.27.4/tocbot.css" />
</Head>
<nav className="js-toc" />
</>
)
また、独自のスタイルを適用する場合、tocSelector で指定した要素(今回だったら.js-toc
)に対してCSSを記述して適用すれば問題ありません。
また、Tocbotでは現在アクティブになっているリンクに .is-active-link
クラスが付与されるため、アクティブな要素のスタイルも変更することが可能です。
私は以下の感じにしてみました!
めっちゃシンプルです(しれっと目次のタイトル追加してます、、)
.js-toc li {
list-style-type: none;
margin-bottom: 4px;
padding-left: 15px;
position: relative;
}
.js-toc a {
text-decoration: none;
transition: color 0.3s ease;
opacity: 0.5;
}
.js-toc a:hover {
opacity: 1;
}
.js-toc a.is-active-link {
font-weight: bold;
opacity: 1;
}
まとめ
この記事では、Next.jsとTypeScriptを使用してTocbotを導入し、目次を作成する方法を紹介しました。目次をクリックすると自動で該当箇所にスクロールする機能や、アクティブなリンクのスタイルを変更する機能など、Tocbotの多機能性を活用することで、ユーザーにとって使いやすい目次を簡単に提供できます。
今後は、さらに自分好みのカスタマイズを加えて、より見栄えの良い目次を作成してみてください🙆♂️
参考リンク
Discussion