vitepress-sideberなるパッケージを導入したのでそのレポートです。
はじめに
今回のアップデートでは、新たにCharacter階層を整備しました。
ここで面倒になるのがサイドバーの生成とprev-nextの生成。
VuePressでは自動で階層下にあるmdをサイドバーにリストアップしてくれますが、VitePressではそれがなくてさあ大変。
また、prev-nextはサイドバーを使って自動生成してくれる機能があり、サイドバーの動的生成ができれば超絶楽になります。
tags階層やposts階層ではコンポーネントを使って自動化していましたが、特にサイドバーは書式が合わないのがなぁ…
というわけでサイドバーの動的生成ができないか調べてみたところ
https://vitepress-sidebar.jooy2.com/
ありました。
使い方
インストール
公式ページ見ろという感じですが、一応npm版だけでも
$ npm i -D vitepress-sidebarTags階層のサイドバー自動化
こんな感じに書きました
import { type DefaultTheme } from 'vitepress'
import { generateSidebar } from 'vitepress-sidebar';
// 中略
function sidebarTags(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Home',
base: '/',
link: '.',
},
{
text: 'About',
link: '/about/',
},
{
text: 'Posts',
link: '/posts/',
},
{
text: 'Tags',
link:'.',
base:'/tags/',
items: generateSidebar({
documentRootPath:'docs',
scanStartPath:'tags',
useTitleFromFileHeading: true,
hyphenToSpace: true,
})
}
]
}generateSidebar()関数がvitepress-sideberで用意される関数です。
documentRootPathでroot階層から見てどこにドキュメントが置いてあるか指定しますscanStartPathでドキュメント階層のどこの階層を探すか指定します(今回は"tags")useTitleFromFileHeading: trueでファイル一番最初に書いてある見出しをサイドバーのテキストにしますhyphenToSpace: trueでハイフン-をスペースに自動変換してくれます。
ちなみにindex.mdはデフォルトで無視してくれます。(無視させない場合、includeFolderIndexFile: trueを入れる必要あり)
これをconfigに適用してビルドするとこんな感じ。

記事数表示は消えますが、まあいいでしょう。
Characters階層のサイドバー自動化
こちらもやりましょう。
import { type DefaultTheme } from 'vitepress'
import { generateSidebar } from 'vitepress-sidebar';
// 中略
function characterSidebarTags(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Characters',
items: [
{
text: "ハブ",
link: "/characters/"
},
{
text: '世界観',
base: '/characters/',
items: [
{
text: '四世界',
link: 'shisekai/'
}
]
},
{
text: 'よくある質問',
base: "/characters/",
link: "faq"
}
]
},
{
text: 'キャラクターリスト',
base: '/characters/',
collapsed: true,
items: generateSidebar({
documentRootPath:'docs',
scanStartPath:'characters',
useTitleFromFrontmatter: true,
sortMenusByFrontmatterOrder: true,
frontmatterOrderDefaultValue: 1000,
excludeFiles:['faq.md'],
excludeFolders:['shisekai'],
}).concat([
{
text: "四世界シリーズ",
base: '/characters/shisekai/',
items: generateSidebar({
documentRootPath:'docs',
scanStartPath:'characters/shisekai',
useTitleFromFrontmatter: true,
sortMenusByFrontmatterOrder: true,
frontmatterOrderDefaultValue: 1000,
})
}
])
},
]
}サイドバーのテキストに関しては、useTitleFromFrontmatterを代わりにオンにしています。これは最初の見出しが英語表記だったりするので、すべて日本語にするために、frontmatterを使っています。
自動生成するのはキャラクターリストなのですが、characters階層にはキャラリストでなく、indexでもないファイル(faq.md)が存在するので、excludeFilesを使ってはじいています。
そしてsortMenusByFrontmatterOrderを使うことで、自由な順番でリストアップできるようにしました。ページのfrontmatterにorderを入れていないページは一番下に来るよう、frontmatterOrderDefaultValue: 1000を入れています。
感想
やっぱり動的生成は最高だな!
面倒なコンポーネント作成や手動書き換えが要らなくなったので、手間がだいぶ省けました。作ってくれた人に大大大大感謝。