本文へスキップ
ロケット団合同会社
StudioCMSカスタムコード

【Studio実装】CMS一覧ページで「ページ内リンク(目次ジャンプ)」を実装する方法

StudioのCMS一覧ページが長くなりすぎて困っていませんか?本記事では、slugとJavaScriptを活用して「目次ナビ(ページ内リンク)」を実装する方法を解説。CMS追加時も自動対応でき、UXを大幅に改善できる実践テクニックを紹介します。

公開 2026年3月13日更新 2026年3月14日読了目安 約6

StudioでCMS一覧ページを作ると、1ページ内に事例や実績を大量に並べる構成になることがあります。件数が増えるほど、次のような悩みが出やすくなります。

  • ページがとても長くなる
  • ユーザーが目的の事例を探しにくい
  • スクロール疲れが発生する 😵‍💫

そこで今回は、ページ上部に目次ナビを作り、クリックした事例まで一気にジャンプできる仕組みの実装方法を解説します。

なぜStudio標準ではできないのか

StudioのCMSリストは、同じレイアウトが複製されて表示される仕組みです。そのため、ボックスにIDを設定すると、すべてのCMSアイテムに同じIDが複製されてしまいます。

HTMLでは、同じIDをページ内に複数置くことはできません。

つまり、CMS一覧の各投稿ごとに個別の

  • ページ内リンク
  • アンカーリンク

を設定するのは、標準機能だけでは難しい仕様なのです。

今回の解決方法

そこで、CMSのslugをキーにしてJavaScriptで制御します。これにより、次の2つが実現できます。

  1. 各事例ブロックに自動でユニークIDを付与
  2. 上部ナビをクリックすると、該当事例までスムーズにスクロール

さらに、CMSを追加しても自動でリンク対応されるのが大きなメリットです。

実装の全体構成

ページは、次の2つのCMSリストで構成します。

① 上部ナビ(目次)

同じCMSモデルのリストを配置し、各アイテムの中に次の要素を置きます。

  • タイトル(クリックするボックス)
  • slug(非表示テキスト)※必須
画像:上部ナビCMSリスト配置イメージ
画像:上部ナビCMSリスト配置イメージ

② 事例本文一覧

こちらも同じCMSモデルのリストです。各アイテムの中に次の要素を置きます。

  • 事例全体の親ボックス
  • slug(非表示テキスト)※必須
  • タイトル
  • 画像
  • 説明文(任意)
画像:事例一覧CMSレイアウト構成
画像:事例一覧CMSレイアウト構成

Studio上で設定するID(重要)

今回使用するIDは4つだけです。

上部ナビ側

  • toc_link — クリックするボックスに付けます
  • toc_slug — slug表示用テキストに付けます(見た目は非表示でOK)
画像:ID設定位置の図解
画像:ID設定位置の図解

本文側

  • case_block — 各事例の外枠ボックスに付けます。※CMSリスト全体ではなく、各アイテム(li)の親ボックスです
  • case_slug — slug表示用テキストに付けます(こちらも非表示でOK)
画像:本文側のID設定イメージ
画像:本文側のID設定イメージ

case_blockul 全体ではなく、各CMSアイテムの親ボックスに付けるのがポイントです。

slugの役割

CMSのslugを、たとえば次のように設定しておきます。

  • case-a
  • case-b
  • case-c

するとJavaScriptが自動で、各事例ブロックに以下のようなIDを付与します。

  • id="case_case-a"
  • id="case_case-b"
  • id="case_case-c"

そして、上部ナビをクリックしたときに、該当の事例位置までスムーズにスクロールする仕組みです。

カスタムコード

以下のコードを、カスタムコードのbody内末尾に設置してください。

<script>
{
  function safeId(value) {
    return String(value || "")
      .trim()
      .toLowerCase()
      .replace(/\s+/g, "-")
      .replace(/[^a-z0-9_-]/g, "");
  }

  function setupCaseAnchors() {
    const caseBlocks = Array.from(document.querySelectorAll('[id="case_block"]'));
    const caseSlugs = Array.from(document.querySelectorAll('[id="case_slug"]'));
    const tocLinks = Array.from(document.querySelectorAll('[id="toc_link"]'));
    const tocSlugs = Array.from(document.querySelectorAll('[id="toc_slug"]'));

    caseBlocks.forEach((block, index) => {
      const slugEl = caseSlugs[index];
      if (!block || !slugEl) return;

      const slug = safeId(slugEl.textContent);
      if (!slug) return;

      const targetId = "case_" + slug;
      block.id = targetId;
      block.style.scrollMarginTop = "120px";
    });

    tocLinks.forEach((link, index) => {
      const slugEl = tocSlugs[index];
      if (!link || !slugEl) return;

      const slug = safeId(slugEl.textContent);
      if (!slug) return;

      const targetId = "case_" + slug;

      link.style.cursor = "pointer";

      link.addEventListener("click", (event) => {
        event.preventDefault();

        const target = document.getElementById(targetId);
        if (!target) return;

        target.scrollIntoView({
          behavior: "smooth",
          block: "start"
        });

        history.replaceState(null, "", "#" + targetId);
      });
    });
  }

  setupCaseAnchors();

  let timer = null;
  const observer = new MutationObserver(() => {
    clearTimeout(timer);
    timer = setTimeout(setupCaseAnchors, 100);
  });

  observer.observe(document.body, {
    childList: true,
    subtree: true
  });
}
</script>

この実装のメリット

  • 長いページでも目的の事例にすぐ飛べる
  • CMS追加時も自動対応できる
  • ページごと複製しなくてよい
  • UX改善につながる
  • slugをキーにして応用しやすい

この実装が向いているページ

次のような、1ページにCMSを大量掲載する構成で特に効果的です。

  • 施工事例一覧
  • 実績一覧
  • 商品カタログ
  • FAQページ
  • CMS記事まとめページ
  • LPの目次ナビ

まとめ

StudioのCMS一覧ページは便利ですが、そのままだと長いページになりやすく、ユーザーが目的の情報にたどり着きにくくなります。

そんなときは、slugを使って各事例に自動でIDを付与し、目次からジャンプできる仕組みを作るのがおすすめです。CMSを追加しても自動対応できるため、運用負荷を増やさずにUXを改善できます。CMS一覧を見やすくしたい方は、ぜひ試してみてください。

Contact

まずは、あなたの「なんだかんだ」を聞かせてください。

ご相談・ご依頼はフォームよりお気軽にご連絡ください。お見積もりまで費用は一切かかりません。

お問い合わせフォームへオンライン面談に全国対応しています。