Create TOC for WP without using Jquery!

monster
Real Talk
Monster
While I am capable of being sociable when necessary, my inherent disposition leans towards being introspective and reserved. I often engage in thoughtful reflection on various aspects of life.
Share with your friends!

Hello! I haven’t posted in a while! Today I will show you how to create a table of contents for WordPress without using Jquery or any plugin. I use 100% code. Let’s start! 😀

Talk about the best table of contents plugins available on the market!

Having a well-structured and effective table of contents (TOC) is crucial for any website, including WordPress (WP). A TOC serves as a roadmap for visitors, allowing them to navigate the content more efficiently. Let’s explore some of the popular types of TOCs for WP and delve into the importance of a TOC on a website.

  1. Static TOC: A static TOC is manually created and positioned on a webpage. It typically appears at the beginning of an article or on the sidebar, providing users with a quick overview of the content sections. Static TOCs are commonly used for long-form articles or tutorials where users can quickly jump to specific areas of interest.
  2. Dynamic TOC: Dynamic TOCs are automatically generated based on the headings or subheadings present within the content. This type of TOC updates itself as the content changes, making it an ideal choice for websites with frequently updated or expanding scope. Dynamic TOCs enhance the user experience by presenting an up-to-date overview of the content structure.
  3. Collapsible TOC: Collapsible TOCs are designed to save screen space and offer a cleaner user interface. Initially, the TOC displays only the main sections, and users can expand or collapse each division to view or hide its subsections. This style is handy for websites with extensive content or nested subheadings, allowing users to focus on specific sections without overwhelming them with excessive information.
  4. Sidebar TOC: A sidebar TOC is a fixed element positioned alongside the main content, typically on the left or right side of the webpage. It remains visible while users scroll through the content, providing continuous navigation assistance. Sidebar TOCs are commonly used in online documentation, knowledge bases, or websites with multiple sections that require easy access.

Now, let’s discuss the importance of a TOC on a website:

  1. Enhanced User Experience: A well-organized TOC improves the user experience by allowing visitors to grasp the structure of the content quickly. Users can navigate directly to the most relevant sections, saving time and effort.
  2. Improved Accessibility: A TOC enhances the accessibility of the website by providing an alternative navigation option. Users with difficulty scrolling or reading lengthy articles can utilize the TOC to jump to specific sections, ensuring everyone can access the desired information.
  3. SEO Benefits: Search engines consider the structure and organization of a website when ranking search results. By implementing a TOC, you create a logical hierarchy of headings and subheadings, making it easier for search engines to understand and index your content accurately. This can potentially lead to improved search engine visibility and higher organic traffic.
  4. Increased Readability: Long-form content can be daunting to read without proper structuring. A TOC breaks down the content into manageable sections, making it more visually appealing and increasing readability. Visitors are more likely to engage with your content when it is easily scannable and digestible.

A well-designed and functional table of contents is valuable for any website, including WordPress-powered ones. It improves user experience, enhances accessibility, provides SEO benefits, and increases the overall readability of the content. Implementing a TOC creates a user-friendly environment and empowers visitors to navigate your website easily.

Some plugins you can download for free at WP Repo

All are free:

  1. Easy Table of Contents: This plugin automatically generates a table of contents based on the headings in your content. It offers various customization options, including different styles, hierarchical or flat displays, and the ability to exclude specific titles or sections.
  2. Table of Contents Plus: This plugin allows you to easily create a table of contents. It offers features like smooth scrolling, a hierarchical display, a customizable appearance, and the option to exclude specific headings or sections.
  3. LuckyWP Table of Contents: LuckyWP Table of Contents is a lightweight and user-friendly plugin that automatically generates a table of contents for your content. It provides multiple styles, smooth scrolling, and responsive design for optimal viewing on different devices.

What I like and what I don’t like about these plugins:

Advantage
Defect
  1. Free of charge
  2. Easy to use
  1. Using Jquery
  2. Not satisfied with fastidious users

Why don’t I like using Jquery?

JavaScript has evolved significantly over the years, and with the rise of modern web development practices, the question of whether to use jQuery or plain JavaScript has become relevant. Here are some reasons why using JavaScript instead of jQuery is often preferred:

  1. Reduced Code Overhead: jQuery is a feature-rich library designed to simplify JavaScript programming but it comes with a cost. The library adds extra weight to the page, increasing the load time. On the other hand, using plain JavaScript allows you to write code specifically tailored to your needs, eliminating unnecessary overhead and reducing the overall file size.
  2. Improved Performance: jQuery is known to perform slower than plain JavaScript. The library must interpret and process additional code, increasing execution time. By utilizing native JavaScript methods and features, you can often achieve faster and more efficient code execution.
  3. Enhanced Control and Flexibility: Plain JavaScript fully controls your code, enabling you to utilize built-in browser APIs and features directly. This allows for greater customization and flexibility, as you can optimize your code for your project’s requirements. With jQuery, you rely on the library’s functionalities, which may not always align perfectly with your specific needs.
  4. Modern JavaScript Features: JavaScript has significantly evolved with the introduction of ECMAScript standards. Newer versions of JavaScript (such as ES6, ES7, and beyond) offer a wide range of powerful features, including arrow functions, template literals, destructuring, and async/await, which enhance code readability, maintainability, and productivity. These modern features are not available in older versions of jQuery.
  5. Easier Maintenance and Debugging: Using plain JavaScript simplifies code maintenance and debugging. jQuery codebases tend to be larger and more complex, with potential dependencies on various plugins and versions. Using plain JavaScript gives you more control over your codebase, making it easier to understand, debug, and modify when necessary.
  6. Learning and Skill Development: While jQuery can provide a convenient shortcut for beginners to achieve specific functionalities, relying solely on it may hinder the development of core JavaScript skills. As JavaScript is a fundamental language of the web, investing time in understanding and mastering it can open doors to a broader range of possibilities and make you a more versatile developer.

Choosing plain JavaScript over jQuery allows for reduced code overhead, improved performance, enhanced control and flexibility, utilization of modern JavaScript features, easier maintenance and debugging, and fosters skill development. While jQuery continues to have its use cases, especially in legacy projects or specific scenarios where its features are necessary, it’s worth considering plain JavaScript for a more streamlined and optimized web development experience.

So let’s create a TOC for our website without using Jquery!

First, I am using the GeneratePress theme, so I think it will be a little easier if you use it! If you use another article, it’s okay. You can still do it for free!

The Javascript library that I use to guide you is tocbot.js

https://tscanlin.github.io/tocbot/

Tocbot is a JavaScript (JS) library that helps create a table of contents (TOC) from headings in an HTML document.

This library uses DOM methods and avoids jQuery & jQuery UI dependencies. If you are an advanced WordPress user, you know that this is a big plus.

Tocbot includes features:

  • Find out the title of the post (like h2)
  • Create links to those sections
  • Tell readers where they are on the page

So we need to be more specific! Here is the JS file you need!

JavaScript
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.21.0/tocbot.min.js"></script>
JavaScript

You can download the latest JS by following this link: https://cdnjs.com/libraries/tocbot

After adding the script, you need to initialize it so that Tocbot knows where you want the table of contents on the post and what you want to add there.

Add these lines of code right above the JS script:

JavaScript
<script>
window.addEventListener('load', (event) => {
 document.querySelectorAll('h2').forEach(function(el, i) {
    el.id = i
  }) 
tocbot.init({
// Where to render the table of contents.
tocSelector: '.toc',
// Where to grab the headings to build the table of contents.
contentSelector: '.content-area',
// Which headings to grab inside of the contentSelector element.
headingSelector: 'h2',
// For headings inside relative or absolute positioned containers within content.
hasInnerContainers: true,
// Headings offset between the headings and the top of the document (this is meant for minor adjustments).
headingsOffset: 40,
// Smooth scroll offset.
scrollSmoothOffset: -40,
  });
});
</script>
JavaScript

Note:

.toc is where you want the table of contents to be displayed
.content-area is the content area you want Tocbot to search for title tags

Although Tocbot has a CSS library, I don’t use it that way. I want to customize the CSS to my needs.

CSS
<style>
@media screen and (min-width: 1024px) {
.inside-left-sidebar {
display: flex;
flex-direction: column;
max-height: calc(100vh - 80px);
position: sticky;
top: 50px;
}
.toc>.toc-list li {
list-style: none;
margin-right: 5px;
}
.toc-list {
max-height: 320px;
overflow-y: scroll;
}
.toc-list::-webkit-scrollbar {
width: 4px;
background: 0;
} 
.toc-list::-webkit-scrollbar-thumb {
background: #eeeeee;
border-radius: 8px;
}
#mermaid-toc
.is-active-link {
color: #137575 !important;
}
#mermaid-toc
a.toc-link {
padding: 4px 0;
display: block;
line-height: 1.5;
font-size: 14px;
overflow: hidden;
color: #6f7672;
-webkit-transition: all .33s ease-out;
-moz-transition: all .33s ease-out;
-o-transition: all .33s ease-out;
transition: all .33s ease-out;
}
#mermaid-toc
a.toc-link:hover {
color: #001107;
}
.post-navigation-left .nav-title {
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 24px;
color: #001107;
padding: 0 0 10px 0;
}
.post-navigation-left .nav-title:before {
content: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2214%22%20viewBox%3D%220%200%2020%2020%22%20fill%3D%22none%22%20stroke%3D%22%236f7672%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M17%209.5H3M21%204.5H3M21%2014.5H3M17%2019.5H3%22%2F%3E%3C%2Fsvg%3E);  
padding-right: 7px;
}
}
@media screen and (max-width: 768px) {
#mermaid-toc-mobile {
padding: 20px 20px 15px;
background: #F7F9FA;
border-radius: 6px;
margin-bottom: 1.5em;
border: 1px solid rgb(0 34 15 / 5%);
}
#mermaid-toc-mobile
.toc>.toc-list li {
list-style: none;
margin-right: 5px;
margin-bottom: 0 !important;
}
#mermaid-toc-mobile
.toc-list {
max-height: 300px;
overflow-y: scroll;
}
#mermaid-toc-mobile
ol.toc-list {
margin: 0 !important;
}
#mermaid-toc-mobile
.toc-list::-webkit-scrollbar {
width: 4px;
background: 0;
}
#mermaid-toc-mobile
.toc-list::-webkit-scrollbar-thumb {
background: #a1a6a3;
border-radius: 8px;
}
#mermaid-toc-mobile
a.toc-link {
padding: 5px 0;
display: block;
line-height: 1.65;
font-size: 16px;
overflow: hidden;
color: #137575;
-webkit-transition: all .33s ease-out;
-moz-transition: all .33s ease-out;
-o-transition: all .33s ease-out;
transition: all .33s ease-out;
}
#mermaid-toc-mobile
a.toc-link:hover {
color: #137575;
}
.post-navigation-inline .nav-title {
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 24px;
color: #001107;
padding-bottom: 10px;
}
.post-navigation-inline .nav-title:before {
content: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2214%22%20viewBox%3D%220%200%2020%2020%22%20fill%3D%22none%22%20stroke%3D%22%236f7672%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M17%209.5H3M21%204.5H3M21%2014.5H3M17%2019.5H3%22%2F%3E%3C%2Fsvg%3E);  
padding-right: 7px;
}
}
</style>
CSS

So the file you need to add is this file!

HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.21.0/tocbot.min.js"></script>
<script>
window.addEventListener('load', (event) => {
 document.querySelectorAll('h2').forEach(function(el, i) {
    el.id = i
  }) 
tocbot.init({
// Where to render the table of contents.
tocSelector: '.toc',
// Where to grab the headings to build the table of contents.
contentSelector: '.content-area',
// Which headings to grab inside of the contentSelector element.
headingSelector: 'h2',
// For headings inside relative or absolute positioned containers within content.
hasInnerContainers: true,
// Headings offset between the headings and the top of the document (this is meant for minor adjustments).
headingsOffset: 40,
// Smooth scroll offset.
scrollSmoothOffset: -40,
  });
});
</script>
<style>
@media screen and (min-width: 1024px) {
.inside-left-sidebar {
display: flex;
flex-direction: column;
max-height: calc(100vh - 80px);
position: sticky;
top: 50px;
}
.toc>.toc-list li {
list-style: none;
margin-right: 5px;
}
.toc-list {
max-height: 320px;
overflow-y: scroll;
}
.toc-list::-webkit-scrollbar {
width: 4px;
background: 0;
} 
.toc-list::-webkit-scrollbar-thumb {
background: #eeeeee;
border-radius: 8px;
}
#mermaid-toc
.is-active-link {
color: #137575 !important;
}
#mermaid-toc
a.toc-link {
padding: 4px 0;
display: block;
line-height: 1.5;
font-size: 14px;
overflow: hidden;
color: #6f7672;
-webkit-transition: all .33s ease-out;
-moz-transition: all .33s ease-out;
-o-transition: all .33s ease-out;
transition: all .33s ease-out;
}
#mermaid-toc
a.toc-link:hover {
color: #001107;
}
.post-navigation-left .nav-title {
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 24px;
color: #001107;
padding: 0 0 10px 0;
}
.post-navigation-left .nav-title:before {
content: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2214%22%20viewBox%3D%220%200%2020%2020%22%20fill%3D%22none%22%20stroke%3D%22%236f7672%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M17%209.5H3M21%204.5H3M21%2014.5H3M17%2019.5H3%22%2F%3E%3C%2Fsvg%3E);  
padding-right: 7px;
}
}
@media screen and (max-width: 768px) {
#mermaid-toc-mobile {
padding: 20px 20px 15px;
background: #F7F9FA;
border-radius: 6px;
margin-bottom: 1.5em;
border: 1px solid rgb(0 34 15 / 5%);
}
#mermaid-toc-mobile
.toc>.toc-list li {
list-style: none;
margin-right: 5px;
margin-bottom: 0 !important;
}
#mermaid-toc-mobile
.toc-list {
max-height: 300px;
overflow-y: scroll;
}
#mermaid-toc-mobile
ol.toc-list {
margin: 0 !important;
}
#mermaid-toc-mobile
.toc-list::-webkit-scrollbar {
width: 4px;
background: 0;
}
#mermaid-toc-mobile
.toc-list::-webkit-scrollbar-thumb {
background: #a1a6a3;
border-radius: 8px;
}
#mermaid-toc-mobile
a.toc-link {
padding: 5px 0;
display: block;
line-height: 1.65;
font-size: 16px;
overflow: hidden;
color: #137575;
-webkit-transition: all .33s ease-out;
-moz-transition: all .33s ease-out;
-o-transition: all .33s ease-out;
transition: all .33s ease-out;
}
#mermaid-toc-mobile
a.toc-link:hover {
color: #137575;
}
.post-navigation-inline .nav-title {
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 24px;
color: #001107;
padding-bottom: 10px;
}
.post-navigation-inline .nav-title:before {
content: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2214%22%20viewBox%3D%220%200%2020%2020%22%20fill%3D%22none%22%20stroke%3D%22%236f7672%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M17%209.5H3M21%204.5H3M21%2014.5H3M17%2019.5H3%22%2F%3E%3C%2Fsvg%3E);  
padding-right: 7px;
}
}
</style>
HTML

If you use the common theme, insert it into the header file, and if you use the paid version of GeneratePress, use it like this.

For it to be displayed on mobile, you must insert this code into the function.php file!

PHP
<?php
function insert_mobile_html_before_first_h2($content) {
    if (wp_is_mobile()) {
        $mobile_html = '<div class="post-navigation-inline" id="mermaid-toc-mobile">
                            <div class="nav-title" style="display: block;">Mermaid Toc</div>
                            <div class="toc"></div>
                        </div>';
        $content = preg_replace('/<h2[^>]*>/', '$0' . $mobile_html, $content, 1);
    }
    return $content;
}
add_filter('the_content', 'insert_mobile_html_before_first_h2');
?>
PHP

To make it display on PC, add this HTML to the sidebar.

HTML
<div class="post-navigation-left" id="mermaid-toc">
<div class="nav-title" style="display: block;">Monster TOC</div>
<div class="toc"></div>
</div>
HTML

Here is the CSS to make the GeneratePress Sidebar sticky

CSS
/* Monster - Stick last widgets in sidebars */
@media(min-width: 769px) {
    .inside-right-sidebar,
    .inside-left-sidebar {
        height: 100%;
    }
    .inside-right-sidebar .widget:last-child,
    .inside-left-sidebar .widget:last-child {
        position: -webkit-sticky;
        position: sticky;
        top: 40px;
    }
}
CSS

If you use Generate Blocks pro version, you can choose the function to hide the sidebar with this HTML (mobile version)!

This is simple to use but very beautiful and delicate. You can customize as much as you want. Demo: https://hathaihao.com or https://ydby.co

Let’s listen to music and good night!

Monster
Monster

Good luck! 🙂

Spread the word about this valuable story if you find it helpful.
Post Navi - Monster & Mermaid
Discover the best resources or enjoy some mini-games
Resources
Draw
Rubix
Flappy Bird
Tower
2048
Pokedex
Crypto App
Disclosure: Some of the links in this article may be affiliate links, which can compensate me at no cost if you purchase a paid plan. These are products I’ve personally used and stand behind. This site is not intended to provide financial advice but for entertainment only. You can read our affiliate disclosure in our Legal.

Leave a Comment

Share to...