Webflow
Jan 9, 2023

How to Add a Dynamic Table of Contents to Your Webflow Blog

Improve Time on Site and Navigation with a Table of Contents

8

min read
How to Add a Dynamic Table of Contents to Your Webflow Blog

What is a Table of Contents in a Blog?

A Table of Contents in a blog post is a list of links to different sections within the post. It allows your reader to quickly navigate to the section of the post that they're actually interested in reading. This can be especially useful for long blog posts that your readers want to skim. The table of contents typically appears at the beginning of the post. Sometimes, it may be "floated" on the side of the page so that it is always visible as the reader scrolls down the page.


Why Do You Need a Table of Contents for Your Business Blog?

A Table of Contents Makes Your Blog Post Easier to Navigate

A table of contents gives your reader a clear and structured overview of the blog post's content. They can click on the relevant section they want to read and skip straight to it. You helped your reader answer their question instead of feeling lost staring at a wall of text and bouncing from your site. This is especially necessary on long pages.

A Table of Contents Helps You Rank Higher on Google

A table of contents helps search engines understand the structure of your blog post. When you have direct links to different sections, Google can now extract and use these links in SERP boxes like answers to the People Also Ask section or Featured Snippets.

What Makes a Table of Contents Dynamic?

A dynamic table of contents automatically highlights the current section as the reader scrolls through the post. Your reader can also click on a link to any section in the table of contents. That makes them jump to that section without manually scrolling through your post.

A static table of contents is just a plain text list of sections. Not very helpful.

How to Add Dynamic a Table of Contents in Webflow

You bought a beautiful Webflow template. It looks great. But something is missing from the blog — a table of contents. In this guide, we'll show you how to add a table of contents that floats on the left side of your blog. It helps to have some knowledge of code, but it's not strictly necessary.

Here's an overview of what we're going to do:

  1. Design the individual links for your table of contents in a separate Webflow page
  2. Create a custom field to specify which headings to use in your table of contents
  3. Add a div to house the table of contents on your blog post page
  4. Add some code to the end of the <body> tag

And that's it! You should have a working table of contents after following these three steps.


Section 1: Design the Individual Links in Your Table of Contents

In this section, we will design the individual table of content element links in a dummy page.

Step 1: New Page for Table of Contents

Create a new page in your Webflow site. You can name it "Table of Contents", but the name doesn't really matter.

Create a Table of Content page

Step 2: Create Links Elements

‎You're going to create a Link Block element with a Text Block within it. Give it two classes: toc-item and toc-h2.

Add some padding around it, and choose whatever font size and color you like.

Styling for first link block

‎In the Selector field, open up the Hover state

Hover state

‎and add some background color and border radius so that it's clear to the user when they're hovering over the link

Styling for first link block on hover

‎Copy and paste your link block in the left pane to duplicate it. Put both of them within a container that vertically aligns them to make it easier for you to visualize. Here is the overall structure:

Overall structure for link elements

‎When you copied it, you also applied the same classes. You're going to remove the toc-h2 class and assign it a class toc-h3. You're also going to add some margin to the left side so that it's indented. The end result is:

Styling for second link block

You should now have two elements that look like this in your page:

Link Blocks with Text Blocks within

‎You can rinse and repeat for H4, H5 and H6 if you want, but we recommend stopping at H3, else the levels of indentation get overwhelming.


Section 2: Create a Custom Field to Specify Which Headings to Use in Your Table of Contents

Open the settings for your Blog Posts CMS Collection.

Blog Post CMS Collection Settings

‎Create a new custom field here of type Plain text and label it "Table of Content Headings". Select Text field type "Single line".

Click Save Collection.

Your end user will type "h2,h3" here for all the H2 and H3 section headings to be listed in the table of contents. If they just type "h2", it will just use the H2 headings.


Section 3: Create a Div to House the Table of Contents

Open your blog posts template page

You can find it under CMS Collection pages

Step 1: Create the Div

Drag and drop a div element where you want your table of contents to be.‎

Table of contents div

Step 2: Give the Div an ID

While the div is selected, in the right pane, click on the Settings gear icon. Enter toc in the ID field.

Name the div toc

You can style the div block however you want. Add padding, margin, left align it, put it in a column, etc. It's up to you. We're just going to place it above the RichText‎ body in our guide.

Section 3: Add some Code to the End of the <body> Tag

Open up the settings for the blog posts template page.

Click on the settings gear icon

Scroll down to the section titled "Before </body> tag"

You're going to add some custom code here.

<script>
function strip(html){
   let doc = new DOMParser().parseFromString(html, 'text/html');
   return doc.body.textContent || "";
}


document.getElementById("content").querySelectorAll("{Table of Contents Headings field}").forEach(function(heading, i) {
  // runs a function for all headings inside your rich text element
  let strippedInnerHtml = strip(heading.innerHTML);
  // adds section titles to slugs
  let str = strippedInnerHtml.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
  let displayText = strippedInnerHtml;
  let MAX_LENGTH = 120;
  let truncatedItem = (displayText.length > MAX_LENGTH) ? displayText.slice(0, MAX_LENGTH-1) + '…' : displayText;
  item.innerHTML = truncatedItem;
  // gives each item the text of the corresponding heading
  ("{Table of Contents Headings field}").split(/[, ]+/).forEach(function(x) {
  // runs a function for each item in your headings list
    if (heading.tagName.toLowerCase() == x) {
      item.classList.add("toc-item", "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>

This code was inspired by the Flowrite blog.

Replace the two place in the above code where it says {Table of Contents Headings field} with the actual field you created in Section 2.

Click Add Field to find the custom field you created

‎The final output should look like this:

Replace {Table of Contents Headings} with the actual custom field you created earlier

In case you're curious, the above code does the following:

  1. It searches for all section headings matching the ones provided in the custom field. So if you entered "h2,h3", it will search for all H2s and H3s.
  2. For each heading it finds, it pulls out the heading text.
  3. It creates a URL-friendly version of the heading. So a heading with text "My Important Section" will be turned into my-important-section. It then attaches an ID to each heading HTML element so that your browser can scroll down to the section automatically.
  4. It creates an item with the text (but truncated if it's too long) in the Div with ID toc that you created earlier. It wraps it in a <a href> link element. This is called an anchor link. It also gives it the same classes toc-item and toc-h2 or toc-h3 you defined earlier so that the styles get applied. It links it to the respective heading.

Publish your site, and you're good to go!

When someone writes a new blog post, just make sure they specify the headings in the table of contents in the custom field you created.

If you find it challenging to get non-technical writers and marketers to publish to your Webflow CMS, consider abstracting the technical complexity away from them using Letterdrop's Webflow integration.


You're One Step Closer to Perfect CRO with a Table of Contents on Webflow

A table of contents makes your article easier to navigate — for both people and Google. In 30 minutes, you've set up a table of contents on your Webflow blog. You've improved your chances of articles ranking on Google and are helping readers find what they need quickly (for which they will be very thankful; if only recipe sites would do the same).

Your Webflow site is probably a leaky bucket and losing leads. Our Webflow Blog Design Guides will help you make your site a conversion rate-optimized machine, guiding leads on the perfect journey from Google to your demo form.