Automatic TOC in BLOGGER articles via HTML code

This article illustrates a practical solution for dynamically generating a table of contents within Blogger posts using HTML, JavaScript, and CSS. Starting with an empty container div, the script analyzes the page headings and automatically builds an interactive index equipped with custom styles. It also demonstrates how to visually format the structure through a dedicated stylesheet to highlight the hierarchy of sections. Finally, the article explains the simple modification needed to make the code work seamlessly on other platforms or stand-alone files.

1. Introduction

Every now and then, I use Blogger as a personal system for publishing articles.

The articles are structured with sections and subsections and an initial table of contents.

The articles are mainly written in Org Mode using Emacs.

In this case, the table of contents is generated by the writing system itself during the conversion phase from Org Mode to HTML.

Sometimes, I use other writing systems that do not generate a table of contents.

In such cases, it would be useful to know how to create the table of contents directly from the HTML code.

Recently I found a solution, which I am sharing with you.

2. TOC Container

At the point where you want the automatic generation of the table of contents, insert the following code:

<div id="auto-toc"></div>

This snippet of code is an empty HTML container element, typically used as an insertion point (or anchor) to dynamically generate a table of contents (TOC).

Element analysis:

  • Tag ~<div ...>~: defines an empty container block (Division) inside the HTML document.
  • Attribute ~id="auto-toc"~: assigns a unique identifier to the element within the DOM (Document Object Model).
  • auto-toc conventionally stands for "Automatic Table of Contents".

Since the element has no visible content, its main purpose is to interact with another script, usually JavaScript, as in our case.

3. JavaScript code for TOC generation

Here is the code that must work in combination with the container indicated above.

At the end of the source code, insert:

<script>
document.addEventListener("DOMContentLoaded", function() {
  const tocContainer = document.getElementById("auto-toc");
  const headings = document.querySelectorAll(".post-body h2, .post-body h3");

  if (headings.length === 0 || !tocContainer) return;

  let tocHtml = '<h3>Table of Contents</h3><ul>';

  headings.forEach((heading, index) => {
    if (!heading.id) {
      heading.id = "sezione-" + (index + 1);
    }

    // Check the tag type (H2 or H3) to apply the indentation class
    const isH3 = heading.tagName.toLowerCase() === 'h3';
    const liClass = isH3 ? 'class="toc-h3"' : '';

    tocHtml += `<li ${liClass}><a href="#${heading.id}">${heading.innerText}</a></li>`;
  });

  tocHtml += '</ul>';
  tocContainer.innerHTML = tocHtml;
});
</script>

4. Styling the TOC using CSS

To "beautify" the document, you can also use style sheets, as in the following example:

<style>
#auto-toc {
  background-color: #f8f9fa;
  border: 1px solid #e9ecef;
  border-left: 4px solid #0056b3;
  padding: 15px 20px;
  margin: 20px 0;
  border-radius: 4px;
}

#auto-toc h3 {
  margin-top: 0;
  margin-bottom: 10px;
  font-size: 1.1rem;
  color: #333;
}

#auto-toc ul {
  list-style-type: none !important;
  padding-left: 0 !important;
  margin-left: 0 !important;
  margin-bottom: 0;
}

#auto-toc li {
  list-style-type: none !important;
  margin-bottom: 6px !important;
}

#auto-toc a {
  text-decoration: none;
  color: #0056b3;
}

#auto-toc a:hover {
  text-decoration: underline;
}
  #auto-toc li.toc-h3 {
  margin-left: 20px !important; /* Indentation to the right of the H3 element */
  font-size: 0.95em;           /* (Opzionale) leggermente più piccolo per gerarchia */
}
</style>

Regarding the CSS code, I prefer inserting it directly inside the article. However, this is a personal choice.

It is usually recommended to insert the CSS code into the theme's source code so that it takes effect across all articles.

5. Does it work only in Blogger?

The code is in HTML format and, therefore, one would expect it to work outside of Blogger as well.

In reality, that is not the case.

In Blogger theme code (both classic and modern), the tag or variable that prints the post content is almost always wrapped inside an HTML element like <div class="post-body entry-content">...</div>.

Therefore, in Blogger, the table of contents works because the platform automatically wraps the text of each post inside a container with the CSS class .post-body.

If you try to open the same document locally (as a stand-alone .html file in a browser) or in another editor, that outer div does not exist, causing the search for h2 and h3 elements to fail.

To make the source code work outside of Blogger as well, you can either wrap the content in a <div class="post-body"> or modify the line:

const headings = document.querySelectorAll(".post-body h2, .post-body h3");

into this:

const headings = document.querySelectorAll("h2, h3");

The difference is as follows: the snippet ".post-body h2, .post-body h3" becomessemplicemente "h2, h3".

Thank you for your attention.

Comments

Popular posts from this blog

Two open source tools for editing PDF documents: GUI versus CLI.

MS Windows: xcopy and robocopy with mentions of batch procedures and rsync.

About LaTeX, standalone, PDF and PNG