Newtのマークダウンにtocbotを対応させる方法【Astro】
- 03 Dec, 2024
はじめに
tocbot を使用して目次を表示させていましたが、コンテンツ管理システムを microCMS から Newt に移行した際に、Newt では h タグに自動的に ID が付与されないことが判明しました。このままでは tocbot の active 機能が動作しません。そのため、今回、h タグに自動で ID を振り分ける対応を実施しました。
実装内容
ここでは、cheerio を用いて HTML に含まれる h2 や h3 タグに順番に ID を自動で付与する方法について説明します。
---
import * as cheerio from 'cheerio';
export async function getStaticPaths() {
const { items: posts } = await newtClient.getContents<Article>({
appUid: 'blog',
modelUid: 'article',
query: {
select: ['title', 'slug', 'body'],
},
});
return posts.map((post) => ({
params: { slug: post.slug },
props: {
post
}
}));
}
const { post } = Astro.props;
const $ = cheerio.load(post.body);
let headingCounter = 0; // カウンターを初期化
// h2とh3にIDを自動付与
$('h2, h3').each((_, elm) => {
headingCounter++; // カウンターをインクリメント
const generatedId = `heading-${headingCounter}`; // IDを生成
$(elm).attr('id', generatedId); // IDをタグに付与
});
// 処理後のHTMLを取得
post.body = $.html();
---
<div set:html={post.body}></div>
上記のコードを使用することで、以下のように ID が付与された HTML を得ることができます。
<h2 id="heading-1">First Heading</h2>
<p>Some content here.</p>
<h3 id="heading-2">Subheading 1</h3>
<p>More content.</p>
<h2 id="heading-3">Second Heading</h2>
<h3 id="heading-4">Subheading 2</h3>
<p>Even more content.</p>
おわりに
今回の対応により、Newt でも tocbot を正常に動作させることができました。
Newt、かゆいところに手が届かない仕様が多い気がするので、このように適宜修正していかなければいけませんね💦