Contents
Case: Create an interactive Table of Contents for a long-read article on Webflow like on this page
In-page linking and interactive Table of Contents could help not only with navigation, but also improve the page's SEO performance. Structured ToC wrapped into <nav> tag helps search engines to understand the structure of your page and increase chance to get Jump Links in Google search results.
You can do it easily without code on a static page, while linking to Headings inside RIch Text element on a CSM collection-based Webflow page will require some code to extract headings, assign IDs to them for anchor linking and generate your Table of Contents.
Method:
- Identify a Rich Text element.
- Extract Headlines and their contents.
- Assign IDs to headings.
- Print a ToC inside a <div> block.
Step-by-Step Guide
The ToC will be generated dynamically from headings within a specific rich text element and inserted into a designated container.
1: Prepare your HTML Structure
- Add a Rich Text field to your CMS collection and create a Rich Text block on the page template with the ID rich-text-element. Link it to this field.
- Ad a <div> block as a container for the ToC with the ID toc-container.
2: Add JavaScript to Generate the ToC
Insert the following script to the </body> custom code section of your Collection template page to dynamically generate the ToC based on the headings within the rich-text-element.
- We will use h2, h3, and h4 headings only.
- We will need to automatically assign unique ID's for each heading inside the Rich Text element to enable anchor linking.
- To make our ToC readable, we will add indents to each its item based on the heading level it links to.
<script>
// Function to generate the ToC
function generateToc() {
// Select the rich text element by its ID
var richTextElement = document.getElementById('rich-text-element');
if (!richTextElement) return '';
// Query all h2, h3, and h4 elements within the rich text element
var headings = richTextElement.querySelectorAll('h2, h3, h4');
var toc = '';
// Generate an ID for each heading for anchor linking if it doesn't have one
headings.forEach(function(heading) {
var tagName = heading.tagName.toLowerCase(); // Get the tag name in lowercase
var id = heading.id ? heading.id : heading.textContent.trim().toLowerCase().replace(/\s+/g, '-'); // Generate a unique ID by trimming, converting to lowercase, and replacing spaces with hyphens.
heading.id = id; // Assign the id to the heading
// Dynamically set classes to define indents for each ToC item based on the level of heading it links to. We don't touch h2 as it won't have indent
var indentClass = ''; // Variable to hold the class for indentation
if (tagName === 'h3') {
indentClass = 'indent-1'; // Add indent-1 class for h3 elements
} else if (tagName === 'h4') {
indentClass = 'indent-2'; // Add indent-2 class for h4 elements
}
// Create a list item with an anchor link pointing to the heading ID. Assign a class to each <li> according to the heading level.
toc += '<li class="' + indentClass + '"><a href="#' + id + '">' + heading.textContent + '</a></li>';
});
return toc;
}
// Function to insert ToC into the container
function insertToc() {
var toc = generateToc(); // Generate the ToC
var tocContainer = document.getElementById('toc-container'); // Select the #toc-container element
tocContainer.innerHTML = '<nav><ul>' + toc + '</ul></nav>'; // Wrap the ToC into a <nav> and <ul> elements
}
// Call insertToc function when the page is loaded
window.onload = insertToc;
</script>
Key functions:
- generateToc(): Extracts h2, h3, and h4 headings from the Rich Text element, assigns IDs to them, and creates a structured list of links pointing to these headings.
- insertToc(): Inserts the generated list into a container element and wraps it into <nav> and <ul> tags.
- window.onload: Ensures the ToC is created and inserted after the page is fully loaded.
3: Add CSS for the ToC Styling
Insert the following CSS to style the ToC into the <head> of your page. It includes styling for the list, links and indentation for different heading levels to show the structure.
You can also create a div block on the page with same ID's, classes and structure to style it via Webflow designer interface, but we put the css code here to show the structure.
<style>
/* Styles for ToC list */
#toc-container ul {
list-style: none; /* Remove bullets from the list */
padding-left: 0;
}
/* Styles for ToC list items with indentation levels — we use .indent-# classes to show the logic. */
#toc-container .indent-1 {
padding-left: 20px;
}
#toc-container .indent-2 {
padding-left: 40px;
}
/* Styles for ToC links */
#toc-container a {
display: inline-block;
font-family: Poppins;
font-size: 16px;
text-decoration: underline 0.5px;
color: #d8d8d8;
transition: color 0.3s;
line-height: 1.2;
}
/* Styles for link on hover */
#toc-container a:hover {
color: #cff7a4;
}
</style>
Done!
PS. Don't forget to use descriptive yet short headings — this will improve SEO even more along with the clickable ToC. Share your thoughts and cases in comments.
Related hacks
MNNGFUL Inc.