☻ Noureddine Made This
Back to home page

How to guide

Introduction

While working on a client's Webflow website, I needed a table of contents for each product information page and advice blog post. The problem was that this needed to be a dynamically generated list that included anchor tags to each specific section or chapter based on the content in a rich text field.

I looked at solutions online but only came across half solutions or solutions for full collections and not for the content inside of each collection item. So I decided to make my own.

The solution I came up with is super simple and allows you to customise it to your exact needs. All we need to do is give two elements on the page a unique ID and then add 15 lines of custom code.

Please note that to be able to create dynamic anchor tags you will need to be able to enter custom code which means a paid account or site plan is required.

CMS Collection settings

In this example, my collection is a very basic barebones blog. The collection is called posts and it has the 3 fields:

  • Name
  • Slug
  • Body (Rich text field)

Your collection can look different and have many other fields but remember that we're trying to dynamically generate anchor tags from content inside of a rich text field. So we need at least one in there.

Setting up our page

First we need to navigate to the CMS collection pages and select the template for our collection.

CMS Collection pages

Once inside that template, we need 2 main elements on the page. A rich text element, where the content will be displayed and a div block element, where we will place the dynamic anchor tags. Each of these elements will have a unique ID so that we can target them in the code.

Div block element

Use the add elements button on the left hand side of the page to add a div block element.

Div block element

After you've added it to the page click on the element settings tab on the right hand side. We need to give this element a unique ID so that we can target it in the code. In the ID field type displayNav.

ID field

Rich text element

Again, use the add elements button on the left hand side to add a rich text element.

Rich text element

Once it's added to the page you will need to connect it to the rich text field in that collection.

Connect to CMS

Once that's done, we're going to go to the element settings tab on the right hand side again. In the ID field type getNav. This is so that we can target it in the code.

ID field

Now that these elements exist on the page and we've given them unique IDs, all we need to do now is add the code which will run thru the rich text and generate dynamic anchor tags and place them in the div element.

Adding the code

Use the add elements button on the left hand side to add an embed element (paid account or site plan required). Make sure to place the embed element at the end of the page so that it runs correctly.

Embed element

In the HTML Embed Code Editor place this code inside:

<script> const getNav = document.querySelector('#getNav');
const displayNav = document.querySelector('#displayNav');
let navItems = getNav.querySelectorAll('h2');
navItems.forEach( i => {
let rawTitle = i.innerText;
let anchor = rawTitle.replace(/[^a-zA-Z0-9]/g, '');
let link = document.createElement('a');
i.setAttribute('id',anchor);
link.innerHTML = rawTitle;
link.setAttribute('href',`#${anchor}`);
link.classList.add('anchor-tag-link');
displayNav.appendChild(link);
});
</script>

This code runs thru the rich text field, finds all the <H2> tags and turns them into anchors and generates links for those anchors. I'll explain it more in depth below, but if you're not interested, you're all set. You can see it in action on the page you're on now, this example page and this other example page.

Diving into the code

Knowing how the code works and what it does helps you further customise it to fit your project.

const getNav = document.querySelector('#getNav');
const displayNav = document.querySelector('#displayNav');

These 2 lines find the unique IDs we assigned earlier so that we can refer to them in the code.

let navItems = getNav.querySelectorAll('h2');

The next line runs thru the getNav (which is the rich text field) and finds every instance of the <H2> tag. In this example we are using <H2> tags to define each anchor or section we want to create a link for.

navItems.forEach( i => {
let rawTitle = i.innerText;
let anchor = rawTitle.replace(/[^a-zA-Z0-9]/g, '');
let link = document.createElement('a');
i.setAttribute('id',anchor);
link.innerHTML = rawTitle;
link.setAttribute('href',`#${anchor}`);
link.classList.add('anchor-tag-link');
displayNav.appendChild(link);
});

This part is where the magic happens. We run thru the navItems we captured from the rich text field and for each one we find we do 8 things:

  1. Take the text of that <H2> tag
  2. Remove spaces and special characters from that text to create a safe URL for the anchor link
  3. Create an <a> tag
  4. Assign the safe URL to the <H2> tag
  5. Give the <a> tag a title
  6. Set the href for the <a> tag
  7. Add a class to the <a> tag so that we can style it
  8. Add the final <a> tag to the div block element we created

Conclusion

That's it! Using only 15 lines of custom code, every post we create within that collection will now have anchor tags dynamically generated from the rich text field.

Have a nice day ☻