Skip to content
気ままに、ちまちま。テックと日常。

【HubSpot】HubSpotページに自動目次を追加する方法【コピペOK】✨

【HubSpot】HubSpotページに自動目次を追加する方法【コピペOK】✨
4:43
目次

📍この記事は ChatGPT がメインで書きつつ、筆者が加筆しています。

🧭 はじめに:この記事でできること

HubSpotブログに、やさしい見た目&アコーディオン対応の目次を追加する方法を紹介します。

HubSpotのブログには、悲しいことに 標準で目次を追加する機能がないのです😢
一応、<a href="#見出し"> のようにアンカーリンクを手動で書く方法👇もあるけれど、
記事が長くなったり更新が多いと、毎回リンクやIDをつけるのは結構大変…💦

 

そこで今回は、見出し(h2・h3)から自動で目次を作る方法を紹介します🪄
読者にもやさしく、自分にもやさしい、目次カスタマイズです🌷

🧃完成系はこんな感じ!🧁

hubspot-toc

※この記事で紹介しているコードは、私のブログの配色や雰囲気に合わせたスタイルになっています🍑
サイトのテーマやブランドカラーに合わせて、フォントサイズや色は自由にアレンジしてください◎

✅ 目次の仕様(今回のゴール)

  • h2, h3 をもとに自動で生成される
  • <details> / <summary> を使ってアコーディオン形式
  • Read Onや関連記事の見出しは目次に含めない
  • H3は階層的に表示+フォントサイズ小さめ
  • サイトカラーに沿ったやさしい色合い🎀

🧩 実装手順(ざっくり)

  1. 目次を表示するカスタムモジュールを作成する

  2. HTML, JS, CSS を設定(モジュールのフィールドは必要なし)

  3. モジュールをブログテンプレートに挿入

  4. デザインや色を自分のサイトに合わせて調整

カスタムモジュールの作り方は👇の記事を参考に~

 

📄 1. module.html

<details class="toc-accordion" open> <summary class="toc-summary"> <span class="toc-arrow" aria-hidden="true"></span>目次 </summary> <div class="toc-wrapper"> <div id="toc"></div> </div> </details>

 

🎨 2. module.css

※ 色やフォントサイズは好きな値に変更してください~

.toc-accordion { margin-bottom: 2rem; font-family: "Noto Sans JP", sans-serif; } /* ▼ 目次トグル */ .toc-summary { background-color: #f0e7d8; color: #958e86; padding: 0.5rem 1rem; font-size: 14px; font-weight: bold; border-left: 4px solid #e5b5b0; cursor: pointer; list-style: none; outline: none; display: flex; align-items: center; gap: 0.5rem; } .toc-summary::-webkit-details-marker { display: none; } /* ▶ / ▼ の切り替えマーク */ .toc-arrow::before { content: "▼"; display: inline-block; transform: rotate(0deg); transition: transform 0.2s ease; font-size: 12px; } .toc-accordion:not([open]) .toc-arrow::before { content: "▶"; } /* ▼ 目次本体 */ .toc-wrapper { padding: 1rem; background-color: #ffffff; border: 1px solid #f0e7d8; border-top: none; } /* タイトル */ .toc-title { font-weight: bold; margin-bottom: 0.5rem; color: #e5b5b0; font-size: 13px; } /* 見出しリストのベース */ .toc-list, .toc-sublist { list-style: none; padding-left: 0; margin: 0; line-height: 1.8; } /* H2見出し(大) */ .toc-h2 > a { display: block; font-weight: bold; color: #958e86; margin: 0.25rem 0; text-decoration: none; font-size: 14.5px; } /* H3見出し(サブ) */ .toc-h3 a { color: #958e86; text-decoration: none; font-size: 13px; margin-left: 0.5rem; display: block; } .toc-h3 a:hover { text-decoration: underline; color: #e5b5b0; }

💻 3. JavaScript(目次の中身を自動生成)

document.addEventListener("DOMContentLoaded", function () { const tocContainer = document.getElementById("toc"); const articleBody = document.querySelector(".blog-post__body"); if (!articleBody) return; const headers = articleBody.querySelectorAll("h2, h3"); let currentH2 = null; let tocHTML = "<ul class='toc-list'>"; headers.forEach((header, index) => { const text = header.innerText.trim(); if (text.toLowerCase().includes("read on")) return; const id = `section-${index}`; header.id = id; if (header.tagName === "H2") { if (currentH2) tocHTML += "</ul></li>"; tocHTML += `<li class="toc-h2"> <a href="#${id}">${text}</a> <ul class="toc-sublist">`; currentH2 = header; } else if (header.tagName === "H3") { tocHTML += `<li class="toc-h3"><a href="#${id}">${text}</a></li>`; } }); if (currentH2) tocHTML += "</ul></li>"; tocHTML += "</ul>"; tocContainer.innerHTML = tocHTML; });

 

🛠️補足)この JS は何をしてるの?

1. ページが読み込まれたら動き始める

document.addEventListener("DOMContentLoaded", function () { ... });

→ ブログページのHTMLが読み込まれたあとに、目次を作る処理をスタートするよ!

2. 目次を入れる場所を探す

const tocContainer = document.getElementById("toc");

<div id="toc"> に、あとで作った目次を入れるよ〜って準備してる🌿

3. 記事本文だけに限定して、h2h3を探す

const articleBody = document.querySelector(".blog-post__body"); const headers = articleBody.querySelectorAll("h2, h3");

→ 関連記事とかサイドバーじゃなく、本文だけを対象にしてるのがポイント!

4. 見出しごとにIDを自動でつける

const id = `section-${index}`; header.id = id;

→ アンカーリンクで飛べるように、見出しに id="section-1" みたいなIDを自動でつけてるよ🛫

5. 見出しの構造を元に、目次のHTMLを作っていく

  • h2 のとき:新しいセクションを作って、その中に h3 を入れられるように準備

  • h3 のとき:ひとつ上の h2 にぶら下げるようにリストを追加

6. 最後に、目次のHTMLをまとめて表示!

tocContainer.innerHTML = tocHTML;

tocHTML という 文字列のかたちで作った目次(<ul>〜</ul>)を、HTMLとしてページに差し込む処理
:目次の中身(HTML)を、実際に表示する場所に入れてる処理

 

🧠 なぜこの実装にしたのか?

🍃 1. <details> / <summary> を使う理由

  • JavaScript不要でアコーディオンが使える(標準タグ)

  • ボタンスタイルの競合を避けられる(テンプレート側のCSSと干渉しないように)

🛡️ 2. document.querySelector('.blog-post__body') に限定

  • 関連記事やサイドバーの見出しを除外

  • content.post_body だけを対象にできるから、安心して運用できる!

🎨 3. 色やフォントサイズをカスタマイズ

  • ブランドカラーに合わせることで、サイト全体に自然になじむ

  • H2 > H3 の階層差が見た目で伝わりやすくなる

🪄 サイトに応じて変えるべきポイント

項目 調整ポイント
querySelector .blog-post__body 以外のクラスを使っている場合は変更する
色・フォントサイズ サイトのブランドカラーに合わせて、CSSの色コードを置き換える
初期状態(開閉) <details open><details> にすれば初期は閉じた状態に

 

⛅ おわりに:やさしい目次で読みやすさUP!

目次があることで、読者は記事全体の流れを把握しやすくなります👀
特に長めの記事を書くことが多い人にはとってもおすすめの実装!

もちろん、アンカーリンクで設定するのも💯なんですが、ポチポチ書き換えるのが面倒… という方はこのカスタムモジュールで作る方法もぜひ取り入れてみてください🫶✨

Reina

Written by Reina

HubSpot CMS (現 Content Hub) をメインに 気になったことをまとめます。猫が好きです