Table of Contents Generator
Generate a Markdown table of contents from your document headings
How to Use This Tool
- Paste your Markdown — Drop your README or document into the input area. Headings are detected as you type.
- Set the depth — Choose how many heading levels to include — most READMEs read best at two or three.
- Copy the table of contents — Copy the generated Markdown list, with anchor links already built for each heading.
- Paste it into your document — Put it after the title and before the first section, then commit.
How the anchor links are built
A table of contents is only useful if every link lands. These anchors follow GitHub’s own slug algorithm, so the TOC works when you paste it into a README:
- Heading text is lowercased.
- Punctuation is removed, but letters in any language are kept.
- Each remaining space becomes one hyphen — and crucially, runs of spaces are not collapsed.
- Repeated headings get a numeric suffix: the second “Usage” is
#usage-1.
| Heading | Anchor |
|---|
## Getting Started | #getting-started |
## API Reference (v2) | #api-reference-v2 |
## Setup & Config | #setup--config |
## What's New? | #whats-new |
## Café Setup | #café-setup |
The third row is the one that catches people out. Removing the ampersand from “Setup & Config” leaves two spaces behind, and GitHub turns each of them into a hyphen. Generators that tidy that into a single hyphen emit a link that silently goes nowhere.
Headings inside code blocks are ignored
Shell comments and Python comments both start with #, so a fenced code block in your README is full of things that look like headings. Line-based TOC generators happily add # Install dependencies from inside a bash snippet to your contents list.
This one tracks fence boundaries and skips everything between them, so only real headings are listed.
Where to put the table of contents
Convention is directly after the title and any badges, before the first real section. Many teams wrap it in HTML comments so an automated tool can refresh the block later without touching the rest of the file:
# My Project
<!-- toc -->
- [Getting Started](#getting-started)
- [Setup & Config](#setup--config)
<!-- tocstop -->
## Getting Started
GitHub also renders its own outline button on READMEs, but that is only visible on github.com — a TOC written into the file travels with the document to GitLab, npm, Obsidian, and anywhere else the Markdown is read.
Frequently Asked Questions
Do the generated anchor links work on GitHub?
Yes. The anchors follow github-slugger, the same algorithm GitHub uses: lowercase the heading, strip punctuation, keep letters from any language, and replace each remaining space with a hyphen. That last rule matters — removing the ampersand from "Setup & Config" leaves two spaces, so the correct anchor is #setup--config with two hyphens. Generators that collapse it to #setup-config produce a link that goes nowhere.
What happens with two headings that have the same name?
Duplicates get a numeric suffix in the order they appear, exactly as GitHub does it. Two "Usage" headings become #usage and #usage-1, so both TOC entries land on the right section instead of both jumping to the first one.
Will headings inside code blocks end up in my table of contents?
No. Shell and Python comments both start with #, so a fenced code block looks like a stack of headings to a naive line-by-line generator. This tool tracks fence boundaries and skips everything between them, so only real headings are listed.
How many heading levels should I include?
Two or three works for most READMEs. Depth 2 gives a short scannable list of top-level sections; depth 3 suits long reference documents where readers jump straight to a subsection. Use the depth control above to compare before you copy.
Where should the table of contents go in the file?
Directly after the title and any badges, before the first real section. Wrapping it in <!-- toc --> and <!-- tocstop --> HTML comments is a common convention that lets automated tooling refresh the block later without disturbing the rest of the document.
Does it work outside GitHub?
The generated list is plain Markdown, so it renders anywhere. Anchor behaviour depends on the viewer: GitHub, GitLab, and most static site generators use this slug style, while some tools use their own prefixes. GitHub also shows its own outline button on READMEs, but that only exists on github.com — a TOC written into the file travels with the document everywhere.