投稿日
最終更新日

Astroの目次がうまくつけられなかった件

目次が導入できなかった件

Astro 目次などで検索してはじめのほうに出てきたrehype-slug/rehype-tocとそれとは別サイトに載ってたrehype-autolink-headingsも追加で導入してみたのですが、私の環境ではうまく動作しませんでした。 remark-tocというプラグインもダメでした。

私の手順ミスの可能性が高いですが、バージョンアップでインストール法が変わったり、動かなくなっているというパターンもありそうです。

なお、執筆時点のAstroのバージョンは5.15.3です。

ちゃんと目次が動作したcustom-tocプラグイン

結論からいうと、こちらの方が作られているastro-custom-tocプラグインは動作させることができました。 Githubはこちら

custom-tocの設定法

基本的には上の方のサイトに載っている手順を踏むだけで導入できました(mdxより前に導入する必要がある点に注意)が、一応こちらにもやり方を残しておきます。 まず、自動インストール用のコマンドを打ちます

npx astro add astro-custom-toc
astro.config.mjs
// @ts-check
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
import { defineConfig } from 'astro/config';
import relativeLinks from 'astro-relative-links';
import expressiveCode from 'astro-expressive-code';
import customToc from 'astro-custom-toc';
// https://astro.build/config
export default defineConfig({
site: 'http://kingyojima.net',
integrations: [expressiveCode(), customToc(), mdx(), sitemap(), relativeLinks(), ],
});

自動インストールでは、integrationsの最後にcustomToc()が追加されるのですが、それだとmdx()より後に追加されてしまうのでmdx()の前に手動で移動させました。 本筋とは関係ないですが、expressiveCode()とrelativeLinksは筆者が別で入れているプラグインで、expressiveCode()もmdx()より前におく必要があります。 mdx()とsitemap()はブログテンプレートを導入すると自動で最初からありました。

custom-tocの使い方

使い方は、markdown/mdxのフロントマターにshowToc: trueを追加して、目次を生成したい場所に<!-- toc -->を記述するだけです。

p0003.mdx
---
title: 'Astroの目次がうまくつけられなかった件'
description: 'Astroに目次をつける。rehype-tocがうまく動作しなかった件'
pubDate: 2025-11-013
tags: ["Astro","blog","ブログテンプレート","目次作成"]
heroImage: '../../assets/blog-placeholder-4.jpg'
showToc: true
---
<!-- toc -->
## 目次が導入できなかった件
...

custom-tocのカスタマイズ(html)

生成された目次を引数に受け取り、最終的なhtmlを返す関数が書けます。 以下のtocTemplateがそれに当たります。これは参考先サイトそのまんまです。またちょっとずつ改良していこうと思います。

content.config.ts
// @ts-check
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
import { defineConfig } from 'astro/config';
import relativeLinks from 'astro-relative-links';
import expressiveCode from 'astro-expressive-code';
import remarkToc from 'remark-toc'
import rehypeToc from 'rehype-toc'
import customToc from 'astro-custom-toc';
const tocTemplate = (html) => {
return `
<aside class="toc">
<h2>目次</h2>
<nav>
${html}
</nav>
</aside>`.trim();
};
// https://astro.build/config
export default defineConfig({
site: 'http://kingyojima.net',
integrations: [expressiveCode(),
customToc({
template: tocTemplate
}),
mdx(),
sitemap(),
relativeLinks(), ],
});

custom-tocのカスタマイズ(maxDepth/ordered)

maxDepthで生成される目次の深さを指定します。 もし<h1>タグがなくて<h2>と<h3>だけだった場合に1を指定すると目次はまったく表示されません。 デフォルトは3で<h2>と<h3>しか使わない予定なので私は指定しませんでした。 参考先のサイトだけではmdxに書くのかastro.config.mjsに書くのか分からなかったので調べてみました。 結論としてはastro.config.mjsに書きます。ordered: trueにする場合も同様です。

astro.config.mjs
// 上部は省略
export default defineConfig({
site: 'http://kingyojima.net',
integrations: [expressiveCode(),
customToc({
template: tocTemplate,
maxDepth: 3,
}),
mdx(),
sitemap(),
relativeLinks(), ],
});