All 14 Table of Contents sections
Where it goes
Add the contents list automatically is the automatic placement. Turn it off and headings still get their anchors, but nothing is added to a post unless you place it yourself.
Position offers four positions:
- Before the first heading — the default, and right on nearly every post: after the opening paragraph, above the first section.
- At the top of the post — above everything, including the introduction.
- After a specific paragraph — for a post with a long lead-in.
- At the end — for a reference page people arrive at from search and scroll back up through.
Display on is the same control every Traslatability plugin uses: everywhere, the front page, or only the post types, pages and categories you choose — with exceptions, address patterns, roles and screen sizes on top.
A contents list is built from the headings of one post, page or product, so it only ever goes on a single one. Archives, the blog index and search results never get one, which is why Placement offers no Archives ticks. The front page gets one only when it is a page of its own.
The cart, checkout and account pages are pages too, but they are left alone: the classic checkout alone has enough headings for a contents card inside the form. To have a list on one of them anyway, set that page's own Table of Contents box to Always show it — or choose Only what I choose below and tick it under Places, or pick it under Specific pages. A rule that names the page is followed; Everywhere and a Pages tick do not reach it.
The same goes for a page that is a directory or a form rather than an article: the front page of our Help Centre plugin, its contact form and a support request. The front page has a heading per topic and per section, enough for a card, and the card used to be drawn inside the first topic. It is left alone now unless the page's own box says Always show it or it is picked under Specific pages. A help article is an article and gets its list as before.
Devices limits the list to the screen sizes you tick, and the floating button, the reading progress bar and the back-to-top button follow it. It is decided by the width of the window rather than by guessing the device, so it works with a page cache.
By hand#
[toc] anywhere in the content puts the list exactly there. Every setting can be overridden on the spot:
[toc design="rail" numbering="nested" columns="2"]design, numbering, layout, title, columns, levels, min, collapsible, folded and width are all accepted, and anything you leave out comes from Settings. folded="yes" starts the list folded, with its Show button to open it.
In the block editor, add the Table of contents block. It has the same overrides in the sidebar: design, numbering, layout, heading, columns, heading levels, minimum headings, folding and width. Anything left as Use the settings (or empty, or unticked) follows Settings. The block is rendered when somebody views the page rather than saved into the post, so it can never go stale against a heading you renamed afterwards.
A post with a [toc] or the block in it does not get the automatic list as well — one list, where you put it. If the list you placed is shorter than its minimum, the post has no list rather than the automatic one somewhere else. Its headings get their anchors either way, even on a page the display rules leave out, so every entry in a list you placed goes somewhere.
In the sidebar#
The Contents (sidebar) block, or the Table of Contents (sidebar) widget under Appearance → Widgets on a classic theme, shows the post's list beside the article. There is nothing to set on either: the list is the one the post already has, in the same design and colours, a size smaller and the width of the sidebar. The block is offered in the Site Editor and under Appearance → Widgets. The post editor does not offer it, since inside a post it would show nothing.
Placed last in its sidebar or column, it stays in view while people read, just under your sticky header and the admin bar, measured the same way a jump to a section measures them. The entry for the section being read is highlighted, a list taller than the window scrolls inside itself to keep that entry in sight, and clicking an entry lands the heading below the sticky header as it does in the post.
How it works, and what follows from that:
- It is drawn from the same headings and settings as the list in the post, so the two always match.
- Where your theme prints the sidebar after the article (most themes with a sidebar on the right, and a block theme's column after the post content), the sidebar has its list as soon as the page appears. Someone browsing with JavaScript off gets it there too, as a plain list of links.
- Where the sidebar comes before the article (a sidebar on the left), the list is moved into it while the page loads, before it is shown, so nothing under it moves. Someone browsing with JavaScript off sees nothing in that sidebar, and has the list in the post as always.
- A site that blocks scripts written into the page (a strict Content Security Policy, or an optimiser that holds such scripts back) still gets all of it, once the plugin's own script has loaded. A sidebar on the left is filled then, and whatever sits under it in the sidebar moves down.
- A post without a list (too few headings, or a post set to never show one) gets nothing in the sidebar, not even the theme's empty widget box. Nor does a screen size your display rules keep the list off.
- It stays in view only as the last thing in its sidebar or column. Above other widgets it would slide over them, so there it keeps its place and scrolls with the page. Inside a sidebar your theme clips (overflow hidden, auto or scroll) it shows without staying in view, since nothing can. On a phone, where a theme puts the sidebar above or below the article, it is part of the page like anything else.
- It shows on single posts and pages. An archive has no one list to show.
- A site that changes its list with the
trtc_navfilter changes the sidebar copy too. The filter's third argument says which one it is looking at:postorsidebar.
Settings → On wide screens, leave the list out of the post while the sidebar shows it is off by default. Switched on, the list in the post stands aside on screens 1024 pixels wide and wider, where the sidebar copy sits beside the article. Where your theme drops the sidebar below the article, and on narrower screens, the list stays in the post, and it always does for anyone browsing with JavaScript off. This is decided while the page loads, before it is shown, so the article does not jump up under the reader. Two cases where it can: a site that blocks scripts written into the page, where it is decided once the plugin's script has loaded, and a sidebar on the right that reaches the browser only after the article has already been shown.
The floating button stays out of the way while the sidebar copy is on screen, and comes back once it is not.
One post at a time#
Every post has a Table of contents box in its sidebar. At the top it says whether this post gets a list, and if not, why not: how many headings it has and how many a list needs, that the display rules or the shop's own pages leave it out, that automatic placement is off, or that a list you placed will show. The line is worked out when the editor opens, from the post as it was last saved; headings that could come from a pattern, another plugin's shortcode or a page builder are only counted when the page is viewed, and the box says so rather than guessing. An image caption or a gallery is not taken for one.
Headings the list cannot see. In the block editor, a second note under that line names what keeps headings out of the list, read from the blocks as you write and checked again half a second after you stop typing:
- Bold lines that look like headings, when the post has too few headings for a list and a list could show on it (Placement adds one, the post is set to Always show it, or you placed one): a paragraph that is all bold, 80 characters or fewer, not ending in a full stop, question mark, exclamation mark or colon, standing on its own rather than in a quote, a list or a table, with something after it in the same group of blocks (an empty paragraph is not something). Make them headings turns each into a Heading block at the first level the list reads, usually H2, and never a second H1 when the list reads H1 too. Each keeps what the paragraph had, as the editor's own Transform to Heading does: its HTML anchor, so a link to it still lands on it, its alignment, additional CSS class, colours and font size, from your palette or your own, and its name in the List View where your WordPress lets you name blocks. On WordPress 6.0, whose own Transform drops the alignment, it is kept all the same. Only the bold markup is dropped: the heading's weight comes from your theme. Where your real headings at that level come both before and after them, they are subsections, and each goes one level below the heading before it. A post split with Page Breaks is counted page by page, as its lists are, unless Settings lists the whole post on every page.
- Sections written as H1s, two or more, when H1 is not one of the levels the list reads. Make them H2 changes them, and moves the headings under them down by as much, so each section keeps its own.
- A heading that skips a level, such as an H4 straight after an H2, with Make it H3. Up to three are named at a time; fixing one brings the next.
- A heading before the first heading of a higher level, such as an H3 before the first H2. Named only, since which of them is wrong is yours to say.
Each note names the lines. A button changes those blocks as they are when you press it, in the editor and nothing else: a message says what changed, with Undo beside it until your next change, Ctrl+Z takes the whole change back in one step, and nothing is saved until you save the post. Nothing is ever changed without a press. With Show template on, the post's own blocks inside the template are read, and the template's are not. Headings inside a synced pattern or a template part are left out, since changing one would change every post that uses it. A post written in the classic editor opens as one Classic block: its bold lines are named, and the buttons appear once you choose Convert to blocks on it. On a post set to Never show it the note does not appear.
In the classic editor there are no blocks to change from here, so the box names the bold lines when the post has too few headings, read from the post as last saved, and says how to make one a heading from the Paragraph menu. Page builders such as Elementor keep their headings in their own layout, where the box cannot see them; nothing here covers them.
Below that are three things: whether the list shows on this post; a heading just for this post; and headings to leave out on this post only.
On this post has four answers:
- Use the settings — whatever Placement says.
- Always show it — the automatic list, whatever the display rules say.
- Only where I place it — no automatic list. A list you put in with the block or
[toc]still appears, and the headings still get their anchors. - Never show it — no list at all, not even one you placed.
That is deliberately all of it. A per-post copy of every setting sounds generous and ages badly — change the design once and a hundred posts keep whatever they were saved with.
Still stuck? Ask the developers who wrote it. We aim to reply within one business day.