ContentWordPress plugin · Free

Indigothorn Table of Contents

A table of contents with zero JavaScript. Your LuckyWP links stay the same.

Switching TOC plugins breaks every shared #anchor link. This one doesn't.

Try it here Coming soon to WordPress.org

Specification

Price
Free, GPL
Version
0.1.0
Requires
WordPress 6.5+, PHP 8.1+
Tested up to
WordPress 7.1
Instead of
LuckyWP Table of Contents
AI
Not used
Key number
~2 ms for a 120-heading post
Recorded in our lab on WordPress 7.1, with voice-overv0.1.0
01Try it

See the idea work, right here.

A small working preview of what the plugin does, on sample data, in your browser. Nothing is sent anywhere.

Anchor preview: type headings, get the same #links LuckyWP madeSample data · runs in your browser

Post content (edit me)

What visitors see · 0 kB JavaScript

Contents
  1. Getting started#Getting_started
    1. What you need#What_you_need
    2. Crème brûlée at the café#Creme_brulee_at_the_cafe
  2. Size & fit#Size_fit
    1. Getting started#Getting_started1
  3. FAQ: returns?#FAQ_returns

Same rules as the plugin: transliteration, duplicates get 1, 2…, skipped headings still use up their id. Collapsing uses native <details>, so it works without JavaScript.

02Compare

Indigothorn Table of Contents vs the alternatives.

Measured in our lab with the same data where there is a number; features from each plugin’s own page otherwise.

FeatureIndigothorn Table of ContentsIndigothorn · freeLuckyWP Table of Contents100k installsEasy Table of Contents600k installs
Front-end JavaScript0 kB3.7 kBScript + jQuery
Front-end CSS1.9 kB, only where shown3.0 kB9.2 kB
Collapses without JavaScriptYesNoNo
Anchors identical to LuckyWPYes—No
Imports LuckyWP settings, shortcodes and blocksYes—No
Still updatedYesNoYes

Measured in our lab with the same posts. Anchors matched real LuckyWP output in 28 of 28 cases (three formats, duplicates, Polish and German characters). “—” means not applicable or not checked.

03Overview

What you get.

01No front-end JavaScript, 1.9 kB CSS
02Anchors identical to LuckyWP in 28/28 cases
03One-click import with a preview
04[lwptoc] shortcodes and blocks keep working

What it does

Indigothorn Table of Contents adds a clean, accessible table of contents to your posts: automatically, with a block, or with the [indigothorn_toc] shortcode. It loads no JavaScript on your pages; collapsing uses the native <details> element and numbering uses CSS.

Moving from LuckyWP Table of Contents? Links to your sections, like example.com/post/#Getting_started, are often shared on social media and indexed by search engines. Most table-of-contents plugins generate anchors differently, so those links break when you switch. This plugin generates the same anchors as LuckyWP, with the same formats and options, and:

  • imports your LuckyWP settings in one click (with a preview of what will be copied),
  • keeps your [lwptoc] shortcodes and LuckyWP blocks working after LuckyWP is deactivated (a migration alias, registered only while no other plugin uses that name),
  • respects LuckyWP's per-post settings (TOC disabled on a post, custom position or title).

Features

  • Automatic insertion before or after the first heading, after the first block, at the top or at the bottom.
  • Minimum number of headings, depth, hierarchical or flat list, decimal or roman numbering (nested or not).
  • Skip heading levels or headings matching a pattern.
  • Anchor formats: from the heading text (transliterated or keeping characters) or a counter; lowercase and dashes options.
  • Collapsible, collapsed by default, smooth scrolling with an offset for sticky headers.
  • Optional: a table of contents that stays visible while scrolling (CSS only) and a highlight of the section being read (a 2 kB script, off by default).
  • Per-post settings in the block editor sidebar: show or hide the automatic table of contents, position, title, minimum headings, depth, numbering and collapsed state.
  • No external services. Nothing leaves your site.

How it compares

Measured in a test lab with the same posts (October 2026):

  • Front-end JavaScript: none by default; the optional current-section highlight adds 2 kB (LuckyWP: 3.7 kB script; Easy Table of Contents: script plus jQuery, js-cookie and sticky-kit).
  • Front-end CSS: 1.9 kB, only on pages with a table of contents (LuckyWP 3.0 kB, Easy Table of Contents 9.2 kB).
  • Collapsing: native <details>, works without JavaScript.
  • Anchors: identical to LuckyWP in all 28 tested cases (three formats, options, duplicates, Polish and German characters).
  • Speed: a 5,000-word post with 120 headings costs about 2 ms extra per page view and no database queries.
04Screenshots

Inside WordPress.

Moving from LuckyWP: a preview of every setting that will be imported.
01Moving from LuckyWP: a preview of every setting that will be imported.
The table of contents on a post: numbered, nested and collapsible, with no JavaScript.
02The table of contents on a post: numbered, nested and collapsible, with no JavaScript.
On a phone.
03On a phone.
Settings.
04Settings.
05Tests

How we checked it.

Automated on every release in an offline lab. The numbers are copied from the latest runs.

63

automated tests: 47 unit and integration, 16 in a real browser

Pass

full regression on WordPress 7.1, 6.5 and multisite (2026-10-15)

0 / 0

Plugin Check errors and warnings, including experimental checks

7

issues found by independent code reviews and fixed, each with a regression test

AA

automated WCAG 2.1 A/AA check of every screen, no serious issues

8.1–8.3

PHP versions in static analysis and coding standards, both clean

06AI & privacy

No AI. Nothing leaves your site.

How it works

Reads your headings on the server. No JavaScript on the page.

AI

Not used. Everything runs on your server.

What leaves your site

Nothing. The plugin makes no outside requests.

07FAQ

Common questions.

Will my existing #anchor links keep working after I switch from LuckyWP?

Yes. Anchors are generated with the same rules as LuckyWP Table of Contents 2.1, including duplicate handling. Keep "Handle [lwptoc] shortcodes" enabled and import your settings.

Does it add JavaScript to my site?

No. The table of contents is plain HTML and a small stylesheet (under 3 kB), loaded only on pages that show a table of contents. The only script is the optional "Highlight the current section" (about 2 kB, no jQuery), loaded only when you switch it on and only on pages with a table of contents. "Stay visible while scrolling" is CSS only.

Can I place the table of contents myself?

Yes: use the "Table of Contents" block or the [indigothorn_toc] shortcode. Both accept the same options as the settings page (title, depth, numbering, toggle and more), for example [indigothorn_toc title="On this page" depth="3"].

Can I use the shorter [toc] shortcode?

Yes, as long as no other plugin or theme on your site uses [toc]: the plugin registers it as a short alias only when that name is free, so it never takes over another plugin's shortcode. [indigothorn_toc] always works.

Can I change the table of contents for one post only?

Yes. In the block editor, open the "Table of contents" panel in the post's sidebar. Every field starts at the site default; what you change applies to that post only and wins over the site settings and over LuckyWP's per-post settings. "Insert automatically: No" stops the automatic table of contents on that post; a block or shortcode you placed yourself still shows.

I customised LuckyWP with code (lwptoc_* hooks). What now?

Your existing [lwptoc] shortcodes keep working while "Handle [lwptoc] shortcodes" is on: [lwptoc] is a migration alias for old posts, registered only when LuckyWP (or another plugin) does not register it. For new posts use [indigothorn_toc] or the block. PHP code hooked into LuckyWP's own lwptoc_* filters has to be moved to the matching tocmig_* filters.

Does it work with block themes and page builders?

Yes. The table of contents is added when the content is rendered, so it works in classic and block themes. Headings added to the content by other plugins are included.

What happens to my data when I delete the plugin?

Settings, including per-post settings, are removed unless you tick "Keep settings when the plugin is deleted". Your posts are never changed: anchors are added when a page is displayed.

Installation

1. Install and activate the plugin.

2. Go to Settings → Table of Contents.

3. Coming from LuckyWP? Check the preview under "Migrate from LuckyWP Table of Contents" and click "Import and deactivate LuckyWP". Otherwise switch on "Insert automatically" or add the "Table of Contents" block to a post.