Streaming live at 10am (PST)

[TUTORIAL] Dynamic Table of Contents on Webflow CMS (no plugins, automatic)

Looking for an easy way to automatically generate Table of Contents for your blog posts or other CMS items?

I recently built a system that dynamically generates ToCs based on the headings (H2, H3, etc.) of any Rich Text field. Super easy to set up, less than 10 lines of code, and no plugins.

Find the full blog post with images, gifs, and code snippets here :point_right: https://www.flowrite.com/blog/dynamic-table-of-contents-on-webflow-cms

4 Likes

@aaro This is so cool!

1 Like

Super cool, thanks a ton for this!

1 Like

it’s great work. Small question – does it have active state?

Thanks! What do you mean exactly?

something like this – http://joxi.ru/GrqjeX6tG98vOm

Hi Aaro,

did you have a chance to look at my question?

Yes! I made that work with an additional code snippet. I’ve included the instructions in the blog post – hope it helps!

activescroll

it’s incredible. You are wonderful. thanks a lot :pray::pray::pray:

1 Like

Hey there Aaro, this is awesome - and a nice replacement for http://projects.jga.me/toc/

I have a question: This is for SEO reasons, and it is the reason I’m considering leaving the TOC jquery plugin.

Is there a way that you can generate the ToCs based on headings through the page, but have the links in the TOC be " p tags vs H2s"

The TOC plugin, unless I’m mistaken, auto creates the TOC links as H2s on the page. This caused me an SEO issue because H2s are now repeated on page.

Here is an example of the current blog post I’m using jquery for.

Hi Aaro,

did you have a chance to look at my question?

Hi @aaro are you able to paste all the code in structure? I can’t seem to make the active toc work.
because the tutorial is adding the code 1 by 1 without showing all the code in final.

I found an error when adding this part

observer.observe(heading);

my current code looks like this


if("{{wf {"path":"table-of-content-based-on","type":"PlainText"\} }}"!=""){

const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    const id = entry.target.getAttribute("id");
    if (entry.isIntersecting) {
      document.querySelectorAll(".active-link").forEach((z) => {
        z.classList.remove("active-link")
      });
      document.querySelector(`a[href="#${id}"]`).classList.add("active-link");
    }
  });
}, { rootMargin: '0px 0px -75% 0px' });

}

document.getElementById("content").querySelectorAll("{{wf {"path":"table-of-content-based-on","type":"PlainText"\} }}").forEach(function(heading, i) { // runs a function for all headings inside your rich text element
observer.observe(heading);
	heading.setAttribute("id", "toc-" + i); // 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 {"path":"table-of-content-based-on","type":"PlainText"\} }}").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", "#toc-" + i); // gives each item the correct anchor link
  document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div
});


Also curious if there’s any update on this, I’m erroring out on the same spot:

observer.observe(heading);

The addition seems to just shut down the TOC JS entirely.

Hi Jon. Everything seems to be working correctly on my end with the same code, but let me see if I can help here. Can you send me a link to your site?

Thanks @aaro, I’m testing out on this example blog post, and here’s the read-only link.

It looks like you’re trying to call the observer function with observer.observe(heading) but you haven’t defined it in the first place. Please make sure to add the code starting with const observer = new IntersectionObserver(entries... from the blog above your current code.

You can also benchmark our blog where I’ve implemented this successfully: How to Write a Reminder Email – with Samples

Hope this helps :blush:

I am new to Webflow and having a dynamic ToC would be great, but I am missing something from this resource - I just cannot understand what are the steps to make it work.

Adding the script is the easy part, but I don’t know what Elements I need to add and where the CSS classes go to generate the ToC for the articles.

What am I missing from the article How to Create Dynamic Table of Contents on Webflow CMS