I made a ToC script before here it works fine but this one little more advanced and has toggle open close and it adds shortcode so you can use it anywhere easily.
// [custom_tableofcontents class_name=".your-custom-container"] shortcode function custom_table_of_contents_shortcode($atts) { // Set default class as '.post-contents' if not provided in the shortcode $atts = shortcode_atts( array( 'class_name' => '.post-contents', // default container class ), $atts, 'custom_tableofcontents' ); // Output the div for the TOC, the toggle button, and the JavaScript ob_start(); ?> <span class="sommaire">Sommaire: </span> <span class="toggle-t-button">[<button id="toggle-toc">Masquer</button>]</span> <div id="table-of-contents" style="display: block;"></div> <script> document.addEventListener("DOMContentLoaded", function() { // Get the container element based on the class_name attribute var contentContainer = document.querySelector("<?php echo esc_attr($atts['class_name']); ?>"); if (!contentContainer) return; // Exit if the container isn't found var headings = contentContainer.querySelectorAll("h2, h3, h4, h5, h6"); var tocContainer = document.getElementById("table-of-contents"); var tocList = document.createElement("ul"); var currentLevel = 2; // Start from h2 var currentList = tocList; // Main list is the root level list headings.forEach(function(heading, index) { var level = parseInt(heading.tagName.substring(1)); // Get the heading level (2, 3, 4, etc.) var anchorId = "toc-heading-" + index; heading.setAttribute("id", anchorId); // Add unique ID to the heading var listItem = document.createElement("li"); var link = document.createElement("a"); link.setAttribute("href", "#" + anchorId); link.textContent = heading.textContent; listItem.appendChild(link); // Adjust list levels based on heading level if (level > currentLevel) { // Create a new nested list var nestedList = document.createElement("ul"); currentList.lastElementChild.appendChild(nestedList); // Nest it in the previous item currentList = nestedList; } else if (level < currentLevel) { // Go back up to the correct level while (level < currentLevel) { currentList = currentList.parentElement.parentElement; currentLevel--; } } currentLevel = level; // Update the current level currentList.appendChild(listItem); // Add the item to the current list }); tocContainer.appendChild(tocList); // Append the final TOC list to the container // Toggle button functionality var toggleButton = document.getElementById("toggle-toc"); toggleButton.addEventListener("click", function() { if (tocContainer.style.display === "none") { tocContainer.style.display = "block"; toggleButton.textContent = "Masquer"; } else { tocContainer.style.display = "none"; toggleButton.textContent = "Afficher"; } }); }); </script> <?php return ob_get_clean(); // Output the HTML and JavaScript } // Register the shortcode add_shortcode('custom_tableofcontents', 'custom_table_of_contents_shortcode');