HelpSite Support Center

Contact Us

Building a Table of Contents inside an article

By default HelpSite does not automatically display a table of contents at the top of your articles. But if you do want an outline of your article to appear at the top or in a sidebar, you do have options!

Manually create Table of Contents

If you want to selectively decide what an article's table of contents should contain and have full control on a per-article basis, you can manually create a table of contents at the top of your articles using our article editor. To link to sections within the same page, see: Using heading links to direct users to a specific part of an article

Automatically generate Table of Contents

However, this is something that you can add by taking advantage of both our Heading links and Custom HTML/CSS features.

Below is an example Article template that you can use if you would like to automatically have a table of contents generated on any article page that contains Headings/Subheadings. It will look like this be default, but can be customized further:

Copy the following code and replace the "Article" template under Customize > Layout & HTML > Article, then ensure the "Use a custom layout" checkbox is enabled.

Paste the following code and save. 

<article class="fr-view">

  <h1>

    {{ article.title | escape }}

  </h1>

  <!-- <p><em>Last updated: {{ article.updated_at | date: "%b %d, %Y" }}</em></p> -->

  <div class="toc" style="display: none; border: solid 1px #ddd; padding: 15px 15px 5px 15px; margin-bottom: 20px; width: fit-content;">

    <p>Table of contents:</p>

  </div>

  {{ article.text }}

</article>

<!-- Table of Contents -->

<script type="text/javascript">

  function buildTableOfContents(selector = 'h1[id]:not(:first-of-type), h2[id], h3[id], h4[id], h5[id], h6[id]') {

    // Select the article tag

    const article = document.querySelector('article');

    

    // Select all the heading tags within the article

    const headings = article.querySelectorAll(selector);

    if (!headings.length) return;

    

    // Create an ordered list element to serve as the table of contents

    const tocList = document.createElement('ul');

   

    let currentList = tocList;

    let prevLevel;

    

    // Iterate over all the headings, create a list item element for each one,

    // and append it to the table of contents list

    headings.forEach((heading) => {

      const listItem = document.createElement('li');

      const link = document.createElement('a');

      link.textContent = heading.textContent;

      link.href = `#${heading.id}`;

      listItem.appendChild(link);

      

      // Determine the nesting level of the heading tag

      const level = parseInt(heading.tagName.charAt(1));

      

      if (prevLevel !== undefined && level > prevLevel) {

        currentList = tocList.lastChild.appendChild(document.createElement('ul'));

      } else if (level < prevLevel) {

        currentList = currentList.parentElement;

      }

      

      currentList.appendChild(listItem);

      prevLevel = level;

    });

    

    return tocList;

  }

  

  document.addEventListener('DOMContentLoaded', (event) => {

    const toc = buildTableOfContents();

    if (toc) {

      document.querySelector('.toc').appendChild(toc);

      document.querySelector('.toc').style.display = 'block';

    }

  });

</script>

Let us know if you have any issues!