What a Markdown TOC Actually Is
A table of contents in markdown is just a list of anchor links. There's no special syntax — it's the standard link syntax ([text](#anchor)) applied to the heading anchors that every markdown parser generates automatically.
## Table of Contents
- [Introduction](#introduction)
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Contributing](#contributing)
How Heading Anchor IDs Are Generated
Every heading in a markdown document gets an anchor ID automatically. The rules (per CommonMark and GitHub):
1. Take the heading text 2. Convert to lowercase 3. Replace spaces with hyphens 4. Remove all characters that aren't letters, numbers, or hyphens
Examples:
## Getting Started→#getting-started## API Reference (v2)→#api-reference-v2## What is it?→#what-is-it## Step 1: Install→#step-1-install## C++ Performance→#c-performance(special chars removed)
Platform Differences in Anchor Generation
Not all markdown renderers generate identical anchor IDs, which can cause TOC links to break:
| Platform | Emoji handling | Accented chars | Notes | | --- | --- | --- | --- | | GitHub | Strips emojis | Preserves | Most common target | | GitLab | Strips emojis | Preserves | Similar to GitHub | | Obsidian | Includes emojis | Preserves | Internal links only | | Pandoc | Strips emojis | Strips | Different algorithm |
When writing a TOC for GitHub specifically, test all links — GitHub's anchor algorithm can surprise you with punctuation-heavy headings.
Using the TOC Generator (Recommended)
Writing TOC links manually is tedious and error-prone, especially for long documents with dozens of headings. The Markdown TOC Generator does it automatically:
1. Paste your markdown document 2. The tool parses every H1–H6 heading 3. Generates the correct anchor links with proper nesting indentation 4. Copy the result and paste at the top of your document
Where to Place the TOC
Best placement: Just below the H1 title and introductory paragraph, before the first H2 section.# Document Title
Brief introduction paragraph...
## Table of Contents
- [Section 1](#section-1)
- [Section 2](#section-2)
## Section 1
...
On GitHub: GitHub renders a floating outline panel for README files, but that's separate from the TOC you add to the document itself. Add the TOC for portability — it works everywhere, not just GitHub.
Nested TOC
Mirror the heading hierarchy in your TOC using nested lists:
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [macOS](#macos)
- [Windows](#windows)
Indent by 2 spaces for each heading level below H2.
Platform-by-Platform Breakdown
GitHub and GitLab
Anchor links work fully. GitHub also auto-generates a collapsible outline panel on the right side of rendered markdown files (2022 feature). The TOC in the document itself is still useful for portability and for older GitHub views.
Obsidian
Obsidian generates heading IDs for anchor links within a document. The "Outline" core plugin shows a navigable heading list in the sidebar. [[Note#Heading]] links to a specific heading in another note.
Notion
Notion does not support anchor links to headings in its markdown import. Adding [text](#heading) imports the link syntax but it doesn't navigate to the heading in Notion.
Discord and Slack
Neither platform renders headings with anchor IDs, so TOC anchor links do not work. There is no equivalent in those contexts.
Static Site Generators
Most SSGs (Jekyll, Hugo, Astro, Next.js) generate heading IDs. Some also have plugins that auto-generate TOCs from headings. Check your SSG's documentation for its anchor generation rules — they sometimes differ from GitHub's.
Common Mistakes
Wrong Anchor Spelling
The most common TOC mistake is getting the anchor ID wrong. Test by clicking every link. When in doubt, use the TOC Generator which derives anchors directly from your headings.
Missing Level-2 Heading for TOC Section
Don't use H3 or H4 for the "Table of Contents" heading — use H2 unless you have a good reason for a different level.
Including H1 in the TOC
The H1 is the document title — it doesn't need to be in the TOC. Start the TOC with H2 headings.
Outdated TOC After Editing Headings
If you rename a heading, the anchor changes and any TOC link pointing to it breaks. After editing headings, regenerate the TOC with the TOC Generator.
Real-World Use Cases
README Files
Long README files for open-source projects almost always include a TOC. Standard sections: Installation, Usage, API, Configuration, Contributing, License.
Technical Documentation
API reference docs, architecture docs, and user guides benefit enormously from a TOC. Readers jump directly to the section they need rather than scrolling.
AI-Generated Long Documents
When you use ChatGPT or Claude to generate a multi-section document, the output often includes a TOC placeholder. Use the TOC Generator to create accurate anchor links before exporting to PDF with MarkdownTools.
See also: Markdown Anchor Links and the TOC Generator tool.
Ready to put this into practice? Paste your markdown into the free MarkdownTools PDF exporter or HTML converter — no signup required.