cheerioを利用して、Next.js x Newt製サイトの記事見出しにアンカーリンクを自動設定する

cheerioは、Node.js上でHTML文字列をパース、jQueryライクなAPIでDOM操作などを行うことができるJavaScriptライブラリです。このチュートリアルでは、cheerioを利用して、Next.js x Newtで作られたブログ記事の見出しにアンカーリンクを自動設定する方法を解説します。

前提条件

  • Newtスペースに、 Blog AppテンプレートをインストールしてAppを作成していること
  • newt-blog-starter-nextjs をローカル環境にclone、 Blog Appと接続して localhost にサイトを立ち上げられていること

参考リンク

概要

Newtから返却される本文データ(HTML文字列)の内容を、cheerioを使って書き換えます。
今回は、本文データのh1~h2要素にa要素を追加することで、見出しをアンカーリンク化していきます。

cheerioをインストールする

まずは、Next.jsプロジェクト(next-blog-starter-nextjs)にcheerioをインストールします。

## npmを利用している場合
npm install --save cheerio

## yarnを利用している場合
yarn add cheerio

記事内のh1~h2要素に対してアンカーリンクを設定する

次に記事ページが実装されている /pages/article/[slug].tsx を編集していきます。

まずはcheerioのload関数をimportします。

+  import { load } from "cheerio";

次にNewtから取得した記事本文のデータ(HTML文字列)を書き換える処理を追加していきます。
getStaticProps関数にNewtからコンテンツを取得する処理があるので、cheerioを使って取得したコンテンツの本文データ(currentArticle.body)を書き換える処理を追加します。

export async function getStaticProps({ params }: { params: { slug: string } }) {
  const { slug } = params;
  const app = await fetchApp();
  const currentArticle = await fetchCurrentArticle({ slug });

+ const $ = load(currentArticle.body); // ①
+ $("h1, h2").each((index, elm) => { // ②
+   const headerText = $(elm).text(); // ③
+   $(elm)
+     .contents()
+     .wrap(`<a id="${headerText}" href="#${headerText}"></a>`); // ④
+ });
+ currentArticle.body = $.html(); // ⑤

  return {
    props: {
      app,
      currentArticle,
    },
  };
}

追加したコードは、処理内容は以下の通りです。

① cheerioのload関数にcurrentArticle.bodyを渡すことでHTML文字列のパースを行います
$("h1, h2").each((index, elm) => { /* 変換処理 */ }) として、h1~h2要素のみを抽出して順次処理を実行します
$(elm).text(); として、抽出した要素からテキストコンテンツを取得します
④ 抽出した要素のコンテンツをa要素で囲みます(id属性とhref属性に③で取得したテキストコンテンツを設定します)
$.html()を実行して、パースしたDOMノードを再びHTML文字列へと変換してcurrentArticle.bodyに再代入します

記事本文データの変換処理は以上となります。
この状態でビルドを実行し、Webサーバーを立ち上げてみます。

# npmを利用している場合
npm run build
npm run start

# yarnを利用している場合
yarn build
yarn start

http://localhost:3000 にアクセスすると、記事ページを開くと次のように見出し部分がリンクに変わっていることが分かります。
記事本文データの変換処理を追加する前の状態は、demoサイトをご覧ください。

スクリーンショット2022-09-2118.15.14.png

見出し部分のHTMLを確認してみると、次のように書き変わっていることが確認できました。

<h2>
   <a href="#最後にFictitiousの特徴を紹介します" id="最後にFictitiousの特徴を紹介します">最後にFictitiousの特徴を紹介します</a>
</h2>

以上でブログ記事の見出しにアンカーリンクを設定する作業は完了となります。

まとめ

このようにcheerioを利用することで、jQueryのようなAPIを使いながらHTMLを柔軟に変換することができます。
今回は見出しにアンカーリンクを設定するだけのシンプルなチュートリアルでしたが、cheerioを使えば目次や脚注の自動生成といったさらに踏み込んだカスタマイズもできますので、ぜひトライしてみていただければと思います。

Newt Made in Newt