How to Create a Table of Content without a Plugin

I had been using a plugin to create a table of contents on all my posts automatically.

I knew that this could be done with a code snippet, so I used an AI tool to create the function.

The AI tool also helped me with the CSS to style the table of content.

I have used this code and it works as expected. Feel free to use it if you like the result.

Code to Create a Table of Content

This code is a WordPress filter function that adds a table of contents to your WordPress posts.

The function does this by looking for all headings in the content (<h2>, <h3>, etc.) and then creating a list of links that point to those headings.

The resulting table of contents is then inserted into the content before the first heading.

function add_table_of_contents_before_first_heading($content) {
  // check if the current post type is "post" and if the content contains at least one heading
  if(get_post_type() == 'post' && preg_match('/<h[2-6]/', $content)) {
    // generate the table of contents
    $table_of_contents = '<div class="table-of-contents">';
    $table_of_contents .= '<h2>Table of Contents</h2>';
    $table_of_contents .= '<ul>';

    // find all headings in the content
    preg_match_all('/<h([2-6])(.*?)>(.*?)<\/h[2-6]>/', $content, $matches);
    foreach($matches[0] as $key => $heading) {
      // extract the heading level and text
      $heading_level = $matches[1][$key];
      $heading_text = $matches[3][$key];

      // add the heading to the table of contents
      $table_of_contents .= '<li><a href="#'.sanitize_title($heading_text).'">'.$heading_text.'</a></li>';

      // add an anchor to the heading
      $content = str_replace($heading, '<a id="'.sanitize_title($heading_text).'"></a>'.$heading, $content);

    $table_of_contents .= '</ul>';
    $table_of_contents .= '</div>';

    // insert the table of contents before the first heading
    $content = preg_replace('/<h[2-6]/', $table_of_contents.'<h2', $content, 1);

  return $content;
add_filter('the_content', 'add_table_of_contents_before_first_heading');

How the Function Works

Here’s a brief explanation of how the code works:

  1. The add_table_of_contents_before_first_heading() function is attached to the the_content filter in WordPress, which means that it will be called automatically whenever WordPress needs to display the content of a post.
  2. The function first checks if the current post type is “post” and if the content contains at least one heading. If either of these conditions is not met, the function returns the content as is.
  3. If both conditions are met, the function generates the table of contents by creating an unordered list (<ul>) and adding list items (<li>) for each heading found in the content. The list items are linked to the corresponding heading using the <a> tag.
  4. The function also adds an anchor to each heading in the content using the <a> tag. This allows the links in the table of contents to jump to the correct heading when clicked.
  5. Finally, the function inserts the table of contents into the content before the first heading and then returns the modified content.

There are several methods to add this code to your functions.php file.

I use a code snippets plugin, however, there are several options like creating a custom plugin or using a child theme’s functions.php file

CSS to Style the Table of Content

You can add this CSS via the theme customizer to make sure that the table of contents generated by the function looks like the table of contents generated by plugins.

.table-of-contents {
    padding: 1em;
    background-color: #f8f8f8;
    border: 1px solid #ddd;
.table-of-contents h2 {
    margin-top: 0;
    margin-bottom: 0.5em;
.table-of-contents li {
    margin-bottom: 0.5em;
.table-of-contents a {
    color: #333;
    text-decoration: none;
.table-of-contents a:hover {
    text-decoration: underline;

Final Thoughts

A TOC allows users to quickly navigate to specific sections of a webpage or document, which can improve their overall experience.

As you can see creating and styling a table of content isn’t that complicated to implement.

More Code Snippets

There are many more snippets where this came from

  1. Add Reusable Blocks to Admin Menu
  2. How to Stop WordPress From Guessing URLs
  3. How to Apply CSS Conditionally
  4. GeneratePress Hooks: Simple Guide
  5. How To Remove the Category From the WordPress URL
  6. How to Delay The Execution of JavaScript without a plugin
  7. How to Disable Heartbeat in WordPress
Manuel Campos, English Professor

Manuel Campos

I am José Manuel. I am writing about things I know and things that I am learning about WordPress. I hope you find the content of this blog useful.






© 2024 WP SURFER • Made with Love in Costa Rica