Build links from stable headings
Start by listing the major sections readers need, then link each item to the matching heading. Use one top-level title and a consistent heading hierarchy. A typical README may contain Introduction, Requirements, Installation, Usage, Configuration, Testing, and License. Link text can differ from the heading, but matching text reduces maintenance mistakes. GitHub creates heading anchors from rendered headings, not from the source file location. Punctuation, repeated words, emoji, and unusual characters can make the final anchor less obvious. Duplicate headings receive distinct anchors, often with a numeric suffix for later occurrences. Prefer unique headings so the target remains predictable. Do not link to a heading that may disappear in a generated version of the document.
Use nested lists for structure
Represent subsections with indented list items. For example, link Installation to #installation, then indent Linux and Windows links beneath it. The nesting shows the reading order and helps users scan a long README. Keep the table of contents near the beginning, after the short project summary or badges. A very small document may not need one. Do not include every heading when the list becomes longer than the content it describes. Exclude temporary notes, repeated navigation labels, and headings used only for visual spacing. If the document uses numbered headings, keep the numbers in the heading text and link target as GitHub generates it. Render the page after edits because source text alone does not prove that an anchor works.
Maintain the table of contents
A table of contents becomes stale when someone renames, adds, or removes a heading. Review it in the same pull request as the heading change. Check links by clicking each entry on the rendered GitHub page. Automated generators can help with long documents, but inspect their output before committing it. Some generators use rules for duplicate headings or punctuation that differ from GitHub's renderer. A manually maintained list gives you control over which sections appear and how they are grouped. For multi-file documentation, link to the file path and optional heading anchor, such as docs/setup.md#requirements. Use relative file links when the navigation should remain inside the repository.
How do you do it step by step?
- 1List the document headings that readers need for navigation and remove minor or repeated entries.
- 2Check that each destination heading has a clear, unique name and a suitable heading level.
- 3Create a Markdown list and link each item to the corresponding GitHub-generated anchor.
- 4Indent subsection links beneath their parent item to reflect the document structure.
- 5Render the page on GitHub and test every table of contents link after heading edits.
Working example
This example creates a compact table of contents for a project README.
## Contents - [Installation](#installation) - [Linux](#linux) - [Windows](#windows) - [Usage](#usage) - [Configuration](#configuration) ## Installation ## Linux ## Windows ## Usage ## Configuration
The Contents list links to the Installation, Linux, Windows, Usage, and Configuration headings. The indentation places the operating-system sections under Installation.
If you rename a heading, update its link and test the rendered anchor. Do not assume punctuation will remain part of the anchor.
Frequently asked questions
- Does GitHub generate a table of contents automatically?
- GitHub can show a document outline in its interface, but it does not insert a visible Markdown table of contents into every file. Add the list yourself or use a compatible generator.
- How does GitHub create heading anchors?
- GitHub derives an anchor from the rendered heading text. Lowercase text and hyphens are common results, while punctuation and duplicate headings can affect the final identifier.
- Can a table of contents link to another file?
- Yes. Use a relative file link and add a heading fragment when needed, such as docs/guide.md#installation.
- Should every heading appear in the table of contents?
- No. Include sections that help readers navigate. Omitting minor headings keeps the list shorter and easier to scan.