Welcome To Snippets.Cloud - The Biggest Code Snippets Library For WordPress
Smart Table of Contents (TOC) Shortcode with Scroll Tracking
Why it’s new and useful:
Table of Contents plugins are everywhere, but most are heavy or lack dynamic features. This snippet introduces a [smart_toc] shortcode that auto-generates a Table of Contents from your post’s headings (H2/H3), highlights the current section as you scroll, and is lightweight—no external dependencies!
1. Add the Snippet to Your Theme’s functions.php or a Custom Plugin
// Smart TOC Shortcode
function wp_smart_toc_shortcode($atts, $content = null) {
global $post;
$content = $content ?: $post->post_content;
// Match H2 and H3 headings
preg_match_all('/<(h[2-3])[^>]*>(.*?)<\/\1>/i', $content, $matches, PREG_SET_ORDER);
if (!$matches) return '';
$toc = '<nav class="smart-toc"><ul>';
$ids = [];
foreach ($matches as $m) {
$tag = strtolower($m[1]);
$text = wp_strip_all_tags($m[2]);
$id = sanitize_title($text);
// Ensure unique IDs
$id = isset($ids[$id]) ? $id . '-' . (++$ids[$id]) : ($ids[$id] = 1) && $id;
$toc .= '<li class="toc-' . $tag . '"><a href="#' . esc_attr($id) . '">' . esc_html($text) . '</a></li>';
}
$toc .= '</ul></nav>';
// Inject IDs into headings in content
$new_content = preg_replace_callback(
'/<(h[2-3])([^>]*)>(.*?)<\/\1>/i',
function($m) use (&$ids) {
$text = wp_strip_all_tags($m[3]);
$id = sanitize_title($text);
$id = isset($ids[$id]) ? $id . '-' . (++$ids[$id]) : ($ids[$id] = 1) && $id;
return '<' . $m[1] . ' id="' . esc_attr($id) . '"' . $m[2] . '>' . $m[3] . '</' . $m[1] . '>';
},
$content
);
// Output TOC + modified content
return $toc . $new_content;
}
add_shortcode('smart_toc', 'wp_smart_toc_shortcode');
// Enqueue scroll tracking JS and TOC styles
add_action('wp_footer', function() {
?>
<style>
.smart-toc { background: #f9f9f9; border:1px solid #eee; padding: 16px; margin-bottom: 24px; border-radius: 6px;}
.smart-toc ul { list-style: none; margin: 0; padding: 0;}
.smart-toc li { margin: 0 0 6px 0;}
.smart-toc a { text-decoration: none; color: #0073aa;}
.smart-toc a.active { font-weight: bold; color: #d54e21;}
.toc-h3 { margin-left: 18px; font-size: 0.96em;}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const tocLinks = document.querySelectorAll('.smart-toc a');
if (!tocLinks.length) return;
const headings = Array.from(tocLinks).map(link => document.getElementById(link.getAttribute('href').substring(1)));
window.addEventListener('scroll', function() {
let activeIndex = 0;
headings.forEach((h, i) => {
if (h && h.getBoundingClientRect().top < window.innerHeight * 0.25) activeIndex = i;
});
tocLinks.forEach((link, i) => link.classList.toggle('active', i === activeIndex));
});
});
</script>
<?php
});
PHP2. How to Use
In your post or page, simply wrap your content with [smart_toc]...[/smart_toc]:
[smart_toc]
<h2>Introduction</h2>
Content...
<h2>Features</h2>
Content...
<h3>Sub-feature</h3>
Content...
[/smart_toc]
Or, if you want to auto-TOC the whole post, just use [smart_toc] at the top of your post.
3. Features
- Auto-generates TOC from H2/H3 headings
- Highlights current section as you scroll
- Lightweight (no jQuery or plugin dependency)
- Works anywhere via shortcode
- Customizable with simple CSS
