Table of content from CMS rich text content

Hi All,
I’m trying to create a floating Table of content based on H2 & H3 in the rich text from CMS.
I did all the steps but it doesn’t seem to work for me :confused:

Has anyone been able to implement this solution: How to Create Dynamic Table of Contents on Webflow CMS
or this: How to create CMS dynamic table of contents (Step by step tutorial)

Tried both and the content table wasn’t generated at all :confused: not sure what I’m doing wrong.
Currently I just have another rich text links linking to anchors - but apparently that doesn’t work from one rich text to another.


Here is my public share link: LINK
(how to access public share link)

Hey Ruthy!

This project only pulls in H2’s, but it could be adapted to work with H2s and H3s.

I followed this tutorial and figured I’d share the cloneable. I hope it works well for you.

Kapture 2022-03-18 at 09.08.24

Thanks for sharing this resource!

In my main text, I have titles (H2) and subtitles (H3). I would like to display only the titles (H2) in the Table of Contents. Is it possible? If yes, how can I do it?

1 Like

Can you share the code you are using?

By default, the code in this project is only supposed to target H2’s.

document.getElementById("content").querySelectorAll("h2").forEach(function(heading, i) { // runs a function for all h2 elements inside your rich text element

Here is the two code snippets used:

<script>
const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    const id = entry.target.getAttribute("id");
    if (entry.isIntersecting) {
      document.querySelectorAll(".active").forEach((z) => {
        z.classList.remove("active")
      });
      document.querySelector(`a[href="#${id}"]`).classList.add("active");
    }
  });
}, { rootMargin: '0px 0px -75% 0px' });
</script>
<script>
document.getElementById("content").querySelectorAll("{{wf {&quot;path&quot;:&quot;toc-based-on&quot;,&quot;type&quot;:&quot;PlainText&quot;\} }}").forEach(function(heading, i) { // runs a function for all headings inside your rich text element
  observer.observe(heading);
  let str = heading.innerHTML; // adds section titles to slugs
  str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs
  heading.setAttribute("id", str); // gives each heading a unique id
  const item = document.createElement("a"); // creates an anchor element called "item" for each heading
  item.innerHTML = heading.innerHTML; // gives each item the text of the corresponding heading
  ("{{wf {&quot;path&quot;:&quot;toc-based-on&quot;,&quot;type&quot;:&quot;PlainText&quot;\} }}").split(",").forEach(function(x) { // runs a function for each item in your headings list
    if (heading.tagName.toLowerCase()==x) {
      item.classList.add("tocitem", "toc-" + x); // gives each item the correct class
    }
  });
  item.setAttribute("href", "#" + str); // gives each item the correct anchor link
  document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div
});
</script>

I have put “H2” in the function you quoted. But still it displays also H3 titles in the TOC.

There is the published page: Icypeas

Hi there ! I also recommend you to use the Finsweet plugin

It’s full free and no script management needed, you just need to put some attributes on your html elements.

Also you can easily choose which headings you want to target :wink:

Thanks for the suggestion! It looks good!

Actually the Finsweet plugin cannot work for me. I create my blog articles using the CMS. With the Finsweet plugin, we need to give the titles a personalised attribute. It seems it is not possible when using the CMS, which is a single ‘Rich Text’ block.

Furthermore, the Finsweet plugin is expensive: $199 per year if I want to be able to use it on a custom domain.

So Duncan, I am still interested in your solution, if you have one! :slight_smile:

I think you’re confused… Finsweet’s attributes are free. I use them on a lot of commercial projects, and extend them regularly for client projects.

You’re definitely thinking of something else.

FS ToC automatically parses your CMS-bound rich text, ID’s your headings for you, and constructs your ToC. Pretty elegant.

1 Like

Good news! It appears to be working for me.

Hey Michael,

I’m somewhat of a newbie here. Could you give a quick summary of how to connect the Finsweet TOC example to the CMS blog post template? Thanks!

I can’t give you any more regarding the install than the Finsweet docs already provide-

However I have some styling notes here-

Ok. I appreciate the prompt reply.

I’m just not understanding how to go from a static blog post (which I can get to work) to a Blog Post template page where these TOC links are generated dynamically based on what’s in the Rich Text of my Blog Post.

I’m missing the connection.

Anyway, thanks.

It’s all in the docs, there isn’t any different in the setup at all.

I build this out for a lot of clients so if you need some dev work done, feel free to drop me a message ( click my name ).