Learning how to add a table of contents without a plugin takes one idea: every heading gets an HTML anchor, and a list at the top of the post links to those anchors. The WordPress block editor supports both halves natively, so a manual outline needs no extra software, no JavaScript and no settings page. On a post with six to ten sections the job takes about 15 minutes, and the result works in any theme.
- Add anchors to each section title
- Create a linked list for navigation
- Style your TOC for better visibility

On this page (built with the exact method described below):
- How anchor links work
- Block editor steps
- Styling and sticky headers
- Using the Table block instead
- Classic Editor and Custom HTML
- Elementor’s widget
- Why the links break
- Search effects
- Manual outline or plugin?
- FAQ
How Anchor Links Make a Table of Contents Work
An anchor link is a hyperlink whose href starts with a hash symbol and points at a named element on the same page. Click it and the browser scrolls there. A table of contents is a list of these links, one per section, which improves user experience on long posts. The section title carries the name, the link repeats it after the hash, and if the two strings differ by a single character the click does nothing. That one rule explains almost every broken outline, and it is all you need to create a table of contents in WordPress by hand.
Why build a TOC in WordPress without a plugin? Many plugins for WordPress that build a TOC parse the post as the page renders and load their own stylesheet and, often, a script. A hand-built list is plain markup stored in the post: no extra requests, nothing to break during an update. The trade-off is maintenance, since a renamed section has to be updated by hand.
How to Add a Table of Contents Without a Plugin in the Block Editor
Gutenberg covers both halves of the job: the Heading block has an anchor field, and any text in a List block can be linked.
Step 1: Finalize Your Section Titles First
Lock down every section title before touching links, because rearranging sections afterwards means redoing anchors. Write a short, lowercase slug beside each title, with hyphens instead of spaces. For “Format as Needed,” a good slug is format-as-needed.
Step 2: Place Anchor IDs on Each Section Title
Click a Heading block, open the block settings sidebar, expand Advanced and type the slug into the HTML anchor field. Leave the hash off here; it belongs only in the link. The WordPress Page Jumps documentation notes that an anchor must be unique within the page, is case-sensitive, and may contain hyphens, underscores, colons and periods.
Step 3: Build the Linked List
Below the introduction, insert a List block and type each section title as a list item. Select the first item’s text, click the link icon in the toolbar (or press Ctrl+K, Cmd+K on a Mac), type #format-as-needed with the hash this time, and press Enter. The anchor text can be shorter than the heading it points to. Repeat for each entry. To nest a subsection under its parent, select the item and click Indent in the toolbar.
Step 4: Preview and Click Every Link
Open the preview in a new tab and click each entry. The address bar should end in the slug, and the matching heading should land at the top of the screen. WordPress never warns about a dead in-page link, so this check is the only safety net.
Styling, Collapsing and Fixing Sticky Header Overlap
Wrap the list in a Group block and type a class such as toc-box into the Group’s Additional CSS class(es) field under Advanced. In a block theme such as Twenty Twenty-Five, the CSS goes in Appearance, then Editor, then Styles, then Additional CSS from the Styles menu. In a classic theme, use Appearance, then Customize, then Additional CSS in the WordPress dashboard.
.toc-box {
border: 1px solid #d0d7de;
border-radius: 6px;
padding: 1rem 1.5rem;
}
:root { scroll-behavior: smooth; }
h2, h3 { scroll-margin-top: 96px; }
@media (prefers-reduced-motion: reduce) {
:root { scroll-behavior: auto; }
}The scroll-margin-top line fixes the most common complaint about a manual TOC: on sites with a sticky header, the target scrolls up underneath the header and the link looks broken. The scroll-margin-top property reserves space above the target; match it to the header’s height. The reduced-motion rule turns smooth scrolling off for readers who limit animation.
Want a collapsible outline? Put the list inside a Details block, part of WordPress core since version 6.3. It outputs native details and summary elements, so it opens and closes without using JavaScript.
Using the Table Block for a Linked Outline
- Click the (+) inserter and search for “Table.”
- Set the column count to 1 and the row count to the number of section titles plus 1 (the extra row holds a label like “In This Post”).
- Enter each section title in its own row.
- Select the text in each cell and link it to
#your-anchor. - Adjust the header section toggle, fixed width cells and colors in the block settings panel.
A grid cannot nest subsections, and screen readers announce it as a table rather than a set of links, so a list is usually the better tool.
The Classic Editor and Custom HTML Version
Older sites can still do this without plugins. The Classic Editor has no anchor field, so the names go in by hand. Switch to the Text tab, add an id attribute to each section title, and paste the outline above the first section. The same markup works in a Custom HTML block:
<nav class="toc-box" aria-label="Table of contents">
<ul>
<li><a href="#choose-a-theme">Choose a Theme</a></li>
</ul>
</nav>
<h2 id="choose-a-theme">Choose a Theme</h2>Add one list line per section. The nav element with an aria-label lets screen reader users find the outline from their landmarks menu, and it makes an extra wrapping div unnecessary.
Elementor’s Table of Contents Widget
Elementor is itself a page builder plugin, and its Table of Contents widget belongs to Elementor Pro, not the free version, so it only fits sites already running Pro. The widget scans the page for the tags chosen in its Include settings and builds the list in the browser with JavaScript.
Drag the widget into place and pick the heading levels to include. The widget handles nesting, numbering, and linking automatically. The Exclude settings take a CSS selector for skipping sidebars or footers, and Minimize Box lets readers collapse the outline on phones.
Why Manual TOC Links Break
A broken TOC link fails silently, and the causes are predictable.
- Mismatched slugs. An anchor of
pricing-tipsand a link to#pricing-tipnever meet. Copy and paste slugs instead of retyping them. - Case differences.
#Pricing-Tipsmissespricing-tips. All-lowercase slugs remove the problem. - Duplicate anchors. Two sections sharing one name send every click to the first.
- A hash in the anchor field. The field then stores a different name from the one the link expects.
- Edited headings. Renaming or reordering sections without updating the outline leaves stale entries.
If a fix does not show on the live post, a page cache is usually serving the old copy; why WordPress changes do not appear right away explains how to clear it. Also, don’t overload the navigation: listing every subsection on a 5,000-word post creates a wall of links nobody reads.
What a Table of Contents Does for SEO
Search Engine Land has documented Google pulling in-page anchors into search results as “jump to” options. Google decides when to display them, so no outline guarantees the feature.
The more dependable SEO benefit is structure. Search engines read heading levels to understand what each section covers: one H1 (the post title, which the theme supplies), H2s for major sections and H3s beneath them. Descriptive titles such as “Step 3: Build the Linked List” make better outline entries than generic labels like “Next Steps.”
If you want to optimize images for better rankings alongside your outline, give each image descriptive alt text so the post can rank for both text and image queries.
Manual WordPress Table of Contents or a Plugin?
| Factor | Manual (No Plugin) | Plugins |
|---|---|---|
| Page speed impact | None (pure HTML) | Loads extra JS and stylesheets |
| Setup time per post | 10 to 15 minutes | Under 1 minute |
| Customization | Full control via stylesheets | Limited to plugin options |
| Maintenance | Manual updates needed | Automatic detection |
| Best for | Small sites, few posts | Large blogs with many posts |
For a WordPress blog publishing fewer than 20 posts per month, the manual approach keeps a WordPress website lean. When should you use a plugin instead? If you publish daily or need an outline on hundreds of existing posts, TOC plugins such as Easy Table of Contents automatically generate a table of contents on every WordPress post and will save hours.
Here is how to add a table of contents without a plugin on your next post: finalize your section titles, paste anchor slugs into each title’s Advanced panel, and build a linked list at the top, then click every link in preview before publishing. If you want to learn WordPress quickly, building manual outlines is a useful hands-on exercise because it teaches anchors, block editor skills and basic styling at once. For another link technique, see the guide on making an image a link.
Frequently Asked Questions About Manual Outlines
How do I add a table of contents without a plugin to an existing post?
Open the post in the block editor, add an HTML anchor to each heading you want listed, then insert a List block below the introduction and link each item with the #your-anchor format. The process is identical for new and existing posts.
Can I link to a section of a post from another page?
Yes. Add the anchor to the end of the full post URL, for example https://example.com/post-slug/#format-as-needed. The browser loads the post and scrolls to that section.
Why does my table of contents link not jump to the right place?
The link and the anchor almost always differ, by a typo, a capital letter or a stray hash in the anchor field. If the page jumps but the title hides under the header, add scroll-margin-top in Additional CSS.
Which heading levels should a manual outline include?
Include every main section at minimum. Add subsections only when they help readers navigate long or complex parts, and leave deeper levels out, since they clutter the outline.
