Long blog posts and documentation articles become much easier to navigate when readers can jump directly to the section they need. A WordPress table of contents — a clickable list of headings at the top of the post that anchors to each section — improves both user experience and SEO by helping readers find specific information quickly and signalling document structure to search engines that may display the TOC as a rich snippet in search results. This fits into the wider topic we cover in our Complete Guide to WordPress How.
WordPress Table of Contents — Plugin-Based Setup
The fastest path to a WordPress table of contents without code is a dedicated plugin. Table of Contents Plus, LuckyWP Table of Contents, and Easy Table of Contents are the three most widely used free options — each automatically scans post headings and generates a linked list that inserts before or within the content.
Easy Table of Contents (the most actively maintained, 400,000+ installs) provides the most configuration options while remaining easy to set up. Install → Settings → Table of Contents → configure: Enable Support for the post types where TOC should appear (Posts, Pages, custom post types) → set the Position (before first heading, before content, after first heading, or via shortcode) → configure which heading levels to include (H2 only, H2+H3, H2+H3+H4) → set the minimum heading count before the TOC appears (typically 3–4 headings). Save → the TOC automatically appears on all posts meeting the heading count threshold without any per-post configuration needed.
Per-post control: Easy Table of Contents adds a “Table of Contents” meta box to the post editor — from there, individual posts can suppress the auto-generated TOC or override global settings. This allows showing a WordPress table of contents on long posts while suppressing it on short posts that technically meet the heading count threshold but do not benefit from navigation. The plugin generates semantically correct anchor IDs from heading text (converting “Main Section Title” to “main-section-title”), making the anchored URLs shareable and linkable — a reader can share a link directly to a specific section within a long article by copying the URL with the heading’s anchor hash. According to Google’s documentation on search appearances, table of contents with anchor links can trigger rich result snippets in search results that display sections from the article directly below the title — a significant visibility improvement for long-form content that covers multiple distinct subtopics a searcher might be looking for.
WordPress Table of Contents in the Block Editor
WordPress’s block editor offers a native approach to the WordPress table of contents: the Table of Contents block (added in WordPress 5.9) generates a TOC from the current post’s heading blocks automatically, without requiring a plugin.
Insert the TOC block: click the “+” block inserter → search “Table of Contents” → insert it at the desired position in the post (typically near the top, after the introduction paragraph). The block automatically populates with links to all heading blocks in the post. Add new heading blocks and the TOC updates in the editor — click “Refresh” in the block toolbar if it does not auto-update. The block renders the correct anchor links pointing to heading IDs on the published post. Configure the TOC’s appearance in the block settings panel: set minimum heading level to include (H2 only, or H2+H3), set the list style (bulleted, numbered, none), and apply custom CSS classes for styling.
The native block WordPress table of contents has limitations compared to plugin-based TOCs: it must be manually inserted into each post (no automatic insertion across all posts), it does not support automatic insertion at a consistent position relative to a specific heading, and it does not generate the numbered TOC style with indented sub-sections that many long-form articles use. For a consistent WordPress table of contents across all posts without manual block insertion on each post, the plugin approach is more practical. For editorial control over exactly which posts have a TOC and where it appears within each post’s unique structure, the block editor approach provides the most flexibility. Our guide on fixing WordPress block editor issues covers the block editor’s table of contents block context alongside the other native Gutenberg blocks that provide structured content organisation without plugin dependencies.
Creating a WordPress Table of Contents With Code
A custom WordPress table of contents implementation using PHP and the_content filter provides complete control over the markup, styling, anchor ID generation, and insertion logic — useful for sites with strict design requirements that plugins cannot satisfy, or sites where adding another plugin is not acceptable.
A basic PHP implementation that parses headings from content and generates a TOC:
add_filter('the_content', function($content) {
if (!is_single()) return $content;
// Find all H2 headings
preg_match_all('/<h2[^>]*>(.*?)</h2>/is', $content, $matches);
if (count($matches[0]) < 3) return $content; // Min 3 headings
$toc = '<nav class="toc"><h3>Contents</h3><ol>';
foreach ($matches[1] as $i => $heading) {
$anchor = sanitize_title(strip_tags($heading));
$toc .= '<li><a href="#' . $anchor . '">' . strip_tags($heading) . '</a></li>';
// Add ID to heading in content
$content = str_replace(
$matches[0][$i],
str_replace('<h2', '<h2 id="' . $anchor . '"', $matches[0][$i]),
$content
);
}
$toc .= '</ol></nav>';
// Insert before first H2
return preg_replace('/(<h2[^>]*>)/', $toc . '$1', $content, 1);
});
This implementation uses sanitize_title() to generate WordPress-consistent anchor IDs — the same function Easy Table of Contents and other plugins use, ensuring anchor URL consistency if the implementation is later replaced by a plugin. The minimum heading count check (3 headings) prevents the WordPress table of contents from appearing on posts that are too short to benefit. Add this to the child theme’s functions.php for a zero-plugin TOC that is fully customisable through CSS. Our guide on WordPress hooks and filters covers the the_content filter that this code uses — understanding the filter’s execution context and priority is important for ensuring the TOC is inserted at the correct position in the content without conflicting with other the_content filters from plugins.
Styling and Accessibility for Table of Contents
A WordPress table of contents that looks like it belongs on the site rather than a generic browser-styled list requires CSS targeting the TOC container and its list items. Styling also affects accessibility — contrast ratios, focus indicators, and visual clarity for the anchor links must meet WCAG standards.
Typical CSS for a styled table of contents:
.toc {
background: #f8f8f8;
border: 1px solid #ddd;
border-radius: 4px;
padding: 1.5rem;
margin: 2rem 0;
max-width: 400px;
}
.toc h3 {
margin-top: 0;
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.toc ol {
margin: 0.5rem 0 0;
padding-left: 1.5rem;
}
.toc a {
color: #0073aa;
text-decoration: none;
}
.toc a:hover, .toc a:focus {
text-decoration: underline;
}
Add the CSS to style the WordPress table of contents in the child theme’s style.css or to the WordPress Customizer’s Additional CSS section. For plugins, each provides its own CSS customisation panel or additional CSS class field that is applied to the TOC container. Accessibility requirements for a WordPress table of contents: wrap it in a <nav> element with an aria-label of “Table of Contents” so screen readers announce it as navigation. Ensure all anchor links have sufficient colour contrast against the TOC background (minimum 4.5:1 ratio for body text, 3:1 for large text). Add visible focus styles for keyboard navigation — the :focus CSS rule above ensures the link is outlined when focused via keyboard, satisfying keyboard navigation accessibility requirements. Our guide on WordPress accessibility covers the full set of WCAG requirements that apply to navigational elements like the TOC, including heading hierarchy, link text quality, and ARIA landmark roles.
Table of Contents SEO Benefits and Schema Markup
The WordPress table of contents delivers SEO impact comes through two mechanisms: the anchor links provide internal links with descriptive anchor text that help search engines understand the document structure, and table of contents sections can appear as rich results in Google Search showing subtopics directly in the search result.
Enable the rich result appearance: Google detects a WordPress table of contents automatically when anchor links connect a TOC item to a heading with a matching anchor ID. No special schema markup is required — the HTML structure of a TOC (a list of anchor links) is the signal Google uses. Verify Google is indexing the TOC correctly: Google Search Console → URL Inspection → test a long article with a TOC → Preview the page as Googlebot — if the TOC links render correctly in the preview, Google can see and potentially use them for rich results. The “FAQ” and “How-To” schema types also contribute to rich results but are separate from the TOC anchoring mechanism — both can be active simultaneously on the same post for different rich result types.
Long-tail keyword targeting improves when a WordPress table of contents creates linkable sections: a post titled “Complete Guide to WordPress Security” with a TOC section “Preventing Brute Force Attacks” creates an anchor link at /complete-guide-wordpress-security/#preventing-brute-force-attacks. This section URL can rank for very specific queries even when the full post ranks for broader terms. Build internal links to specific TOC sections from other posts and from the site’s navigation to amplify this effect — instead of linking to the full post, link to the specific section (/full-post-slug/#specific-section) from posts that are specifically about that sub-topic. This precision internal linking passes link equity to the specific section rather than diluting it across the entire article, improving the section’s visibility for the narrower queries that the section’s content directly addresses. Reviews from Google Search Central confirm that articles with working anchor links are more likely to receive the “Table of Contents” rich result that shows section links directly in search results, providing larger real estate in the SERPs and potentially improving click-through rates for informational content. Our guide on setting up a WordPress XML sitemap covers the complementary SEO infrastructure that ensures the long-form articles with table of contents are discoverable by search engines alongside the rich result optimisation that the TOC provides.
Collapsible WordPress table of contents — where the TOC can be hidden or shown by clicking a toggle — improves mobile user experience on posts with many sections where the expanded TOC takes significant vertical space. Easy Table of Contents includes a collapsible toggle option in its settings: Settings → Table of Contents → check “Enable ‘Contents’ toggle” → the TOC renders with a show/hide button that collapses and expands the list. For custom-coded TOCs, add a simple JavaScript toggle: wrap the TOC list in a container → add a button element → bind a click event that toggles an “open” class → use CSS transitions to animate the expand/collapse. WordPress’s standard jQuery (loaded on the front-end by any plugin that uses jQuery) can handle this without additional dependencies, keeping the toggle implementation lightweight without adding a dedicated JavaScript library for the single animation.
Multi-level WordPress table of contents that shows nested H2 and H3 headings in an indented structure requires detecting heading hierarchy rather than just listing all headings. The Easy Table of Contents plugin handles hierarchy automatically — enabling H2 and H3 in the settings generates a two-level list where H3 headings appear as nested items under their parent H2. For custom PHP implementations, detecting hierarchy requires tracking the previous heading level and wrapping H3 headings in a nested <ol> within the current H2’s list item. The algorithm: iterate through headings in document order, push H2 headings to the main list, nest H3 headings under the preceding H2. Most readers benefit most from a two-level TOC (H2 and H3) — adding H4 and deeper headings produces a TOC that is more complex than the article navigation it is meant to simplify, providing diminishing navigation returns for the added visual complexity.
The WordPress table of contents plugin choice for WooCommerce product pages differs from blog post TOC needs. Product pages with long descriptions, specification sections, and review summaries benefit from a TOC, but WooCommerce uses its own tab system for “Description,” “Additional Information,” and “Reviews” — a TOC that links to headings within the description tab works within that tab’s content, while WooCommerce’s tabs provide top-level navigation between sections. Disable automatic TOC insertion on WooCommerce product pages in Easy Table of Contents settings (uncheck “product” from the supported post types) and instead use the shortcode [toc] within the product description for products that specifically benefit from section navigation within their long descriptions. This targeted approach provides TOC value where it is genuinely useful without cluttering shorter product pages that do not need section navigation beyond WooCommerce’s built-in tabs.
Fixing a WordPress table of contents where anchor links do not scroll to the correct heading is almost always a CSS or JavaScript conflict — either a sticky header covering the target heading when the page jumps to the anchor, or a JavaScript smooth-scroll implementation that does not account for fixed header height. The sticky header offset problem: when a fixed navigation bar covers the top 80px of the page, clicking a TOC anchor link scrolls the heading behind the header. Fix with CSS scroll-margin-top on all headings: h2, h3, h4 { scroll-margin-top: 100px; } — this adds 100px of scroll margin (adjust to match the actual header height) so the heading appears below the fixed header after anchor navigation. This CSS approach is more reliable than JavaScript workarounds and works correctly with browser history navigation (back/forward buttons), which some JavaScript offset approaches handle incorrectly.






