How to Automatically Add a Table of Contents (TOC) to Single Blog Posts in WordPress

Last edited:2025-06-08

Categories: WordPressSEO

Ever written a long blog post and thought, “Wow, even I got lost halfway through this”?
Yeah — your readers probably feel the same.

That’s where a Table of Contents (TOC) saves the day.
It helps users navigate your content, boosts SEO, and makes your article feel organized — like a clean desk after a messy project.

In this post, I’ll show you how to automatically generate a Table of Contents for single posts using a small, smart PHP snippet.


Why a TOC Helps Your SEO 🧭

Here’s why adding a TOC isn’t just for looks:

So yeah, a TOC isn’t just “nice to have.” It’s a subtle SEO and UX powerhouse. 💪


The Code: Automatically Generate a TOC in WordPress

Add the following snippet to your theme’s functions.php file or your custom plugin:

function cv_generate_toc( $content ) {
    if ( is_singular( 'post' ) ) {
        // Find all H2 tags in the post content
        preg_match_all( '/<h2.*?>(.*?)<\/h2>/', $content, $matches );

        if ( empty( $matches[1] ) ) {
            return $content; // No H2 headings found
        }

        // Generate the TOC HTML
        ob_start();
        ?>
        <div id="toc-container" class="toc-container">
            <h3>Table of Contents</h3>
            <ul>
                <?php foreach ( $matches[1] as $heading ) : 
                    $clean_heading = wp_strip_all_tags( $heading );
                    $slug = 'toc-' . sanitize_title( $clean_heading ); ?>
                    <li><a href="#<?php echo esc_attr( $slug ); ?>"><?php echo esc_html( $clean_heading ); ?></a></li>
                <?php endforeach; ?>
            </ul>
        </div>
        <?php
        $toc = ob_get_clean();

        // Add IDs to the H2 headings in the content
        foreach ( $matches[1] as $index => $heading ) {
            $clean_heading = wp_strip_all_tags( $heading );
            $slug = 'toc-' . sanitize_title( $clean_heading );
            $content = str_replace( $matches[0][$index], '<h2 id="' . esc_attr( $slug ) . '">' . $heading . '</h2>', $content );
        }

        // Combine TOC and content
        $content = '<div class="content-toc-wrapper">' . $toc . '<div class="post-content">' . $content . '</div></div>';
    }
    return $content;
}
add_filter( 'the_content', 'cv_generate_toc' );

Add Smooth Scrolling for Better UX

Because we like that fancy scrolling-into-place effect:

function cv_enqueue_custom_toc_scripts() { ?>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            document.querySelectorAll('.toc-container a').forEach(anchor => {
                anchor.addEventListener('click', function(e) {
                    e.preventDefault();
                    document.querySelector(this.getAttribute('href')).scrollIntoView({
                        behavior: 'smooth'
                    });
                });
            });
        });
    </script>
<?php }
add_action( 'wp_footer', 'cv_enqueue_custom_toc_scripts' );

How It Works 🧠

The function looks for all H2 headings in your post.

It creates a TOC at the top, linking each heading to its section.

Each H2 gets a unique id (like #toc-introduction).

JavaScript adds a smooth scrolling effect when clicking TOC links.

Example Output

Table of Contents
• Introduction
• Why SEO Matters
• How to Add TOC in WordPress
• Final Thoughts

When clicked, each link smoothly scrolls to its section — no page jumps, no drama. 🎯

Styling the TOC with CSS 🎨

Want to make your TOC look clean and elegant? Drop this CSS snippet into your theme’s stylesheet or customizer:

.toc-container {
  background: #f9f9f9;
  border: 1px solid #e1e1e1;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 30px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}

.toc-container h3 {
  font-size: 1.2rem;
  margin-bottom: 10px;
  border-bottom: 1px solid #ddd;
  padding-bottom: 5px;
}

.toc-container ul {
  list-style: none;
  padding-left: 0;
  margin: 0;
}

.toc-container li {
  margin: 6px 0;
}

.toc-container a {
  color: #0073aa;
  text-decoration: none;
}

.toc-container a:hover {
  text-decoration: underline;
}

This gives you a modern, clean box that fits nicely with most WordPress themes.
Feel free to tweak the colors and padding to match your design.


Final Thoughts

A Table of Contents is one of those small things that makes a big impact.
It helps readers stay oriented, encourages engagement, and even improves your Google visibility.

If you write long-form content, this is a no-brainer.
Drop it in your functions.php, add a bit of CSS, and your posts just got smarter. 🧩

💡 Bonus idea: You can make your TOC collapsible or sticky for even better usability on long posts!

#TOC#Hooks#User Experience#Content
← Back to Blog