How to Create a Table of Contents in Markdown: Complete Guide
Creating a table of contents (TOC) in Markdown helps readers navigate long documents efficiently. While standard Markdown doesn’t include built-in TOC functionality, there are several effective methods to generate navigation menus for your documents. This comprehensive guide covers automatic generation, manual creation, and platform-specific solutions.
Why Add a Table of Contents?
A well-structured table of contents provides several benefits:
- Improved Navigation: Readers can quickly jump to relevant sections
- Better User Experience: Especially valuable for long-form content and documentation
- SEO Benefits: Search engines can better understand document structure
- Professional Appearance: Makes documents look more organized and complete
Method 1: Automatic TOC Generation
Many Markdown processors and static site generators can automatically generate table of contents from your document headings.
GitHub-Flavored Markdown
GitHub automatically generates a TOC for files in repositories. You can access it by clicking the “table of contents” icon in the file header, but you cannot embed it directly in the document.
Jekyll and GitHub Pages
Jekyll sites can use plugins to automatically generate TOCs:
# In _config.yml
plugins:
- jekyll-toc
Then add this to your layout or post:
{{ content | toc }}
Using Pandoc
Pandoc can generate a TOC when converting documents:
pandoc --toc --toc-depth=3 document.md -o output.html
Method 2: Manual Table of Contents
Creating a manual TOC gives you complete control over structure and appearance.
Basic Manual TOC Structure
## Table of Contents
1. [Introduction](#introduction)
2. [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
3. [Usage Examples](#usage-examples)
4. [Advanced Features](#advanced-features)
5. [Troubleshooting](#troubleshooting)
6. [Conclusion](#conclusion)
Creating Anchor Links
Markdown automatically creates anchor links from headings. The anchor is typically the heading text in lowercase with spaces replaced by hyphens:
# Getting Started
## User Authentication
### OAuth Setup
<!-- Links to these sections -->
[Getting Started](#getting-started)
[User Authentication](#user-authentication)
[OAuth Setup](#oauth-setup)
Handling Special Characters in Headings
For headings with special characters, the anchor generation varies by platform:
# API & SDK Setup
<!-- GitHub link: #api--sdk-setup -->
<!-- Other platforms may vary -->
# Cost ($) Analysis
<!-- GitHub link: #cost--analysis -->
Method 3: JavaScript-Based TOC Generation
For web-based Markdown rendering, JavaScript can dynamically create table of contents.
Simple JavaScript TOC
function generateTOC() {
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
const toc = document.getElementById('table-of-contents');
let tocHTML = '<ul>';
headings.forEach((heading, index) => {
const id = heading.id || `heading-${index}`;
heading.id = id;
const level = parseInt(heading.tagName.charAt(1));
const indent = ' '.repeat(level - 1);
tocHTML += `${indent}<li><a href="#${id}">${heading.textContent}</a></li>`;
});
tocHTML += '</ul>';
toc.innerHTML = tocHTML;
}
This approach is covered in detail in our guide on adding table of contents to markdown using JavaScript.
Method 4: Platform-Specific Solutions
GitBook
GitBook automatically generates TOCs from your document structure:
# Table of contents
* [Introduction](README.md)
* [Chapter 1](chapter1.md)
* [Chapter 2](chapter2.md)
* [Section 2.1](chapter2/section1.md)
* [Section 2.2](chapter2/section2.md)
Notion
Notion provides a /table
command that creates an automatic TOC based on page headings.
MkDocs
MkDocs generates navigation automatically from your mkdocs.yml
configuration:
nav:
- Home: index.md
- User Guide:
- Installation: installation.md
- Configuration: configuration.md
- API Reference: api.md
Hugo
Hugo can generate TOCs using built-in variables:
Customizing TOC Appearance
CSS Styling
.table-of-contents {
border: 1px solid #ddd;
border-radius: 5px;
padding: 20px;
margin: 20px 0;
background-color: #f9f9f9;
}
.table-of-contents ul {
list-style-type: none;
padding-left: 0;
}
.table-of-contents li {
padding: 5px 0;
}
.table-of-contents a {
text-decoration: none;
color: #333;
}
.table-of-contents a:hover {
text-decoration: underline;
color: #007cba;
}
Multi-Level Indentation
For nested TOCs, use proper indentation:
## Table of Contents
- [Chapter 1](#chapter-1)
- [Section 1.1](#section-11)
- [Subsection 1.1.1](#subsection-111)
- [Section 1.2](#section-12)
- [Chapter 2](#chapter-2)
- [Section 2.1](#section-21)
- [Section 2.2](#section-22)
Best Practices for TOC Creation
Structure Guidelines
- Limit Depth: Typically include only H1-H3 headings for readability
- Consistent Naming: Use descriptive, consistent heading names
- Logical Order: Organize sections in a logical, progressive manner
- Regular Updates: Keep TOC synchronized with document changes
Accessibility Considerations
## Table of Contents {#table-of-contents}
<nav role="navigation" aria-labelledby="table-of-contents">
1. [Introduction](#introduction)
2. [Getting Started](#getting-started)
3. [Advanced Topics](#advanced-topics)
</nav>
SEO Optimization
- Use descriptive anchor text
- Include relevant keywords in headings
- Maintain proper heading hierarchy (H1 → H2 → H3)
- Ensure links work correctly across different platforms
Troubleshooting Common Issues
Links Not Working
Problem: TOC links don’t navigate to correct sections
Solutions:
<!-- Ensure heading IDs match links -->
# Getting Started {#getting-started}
[Getting Started](#getting-started)
<!-- Check for special character handling -->
# API & Documentation
[API & Documentation](#api--documentation)
Formatting Issues
Problem: TOC appears as plain text instead of links
Solutions:
- Verify Markdown processor supports linking
- Check that headings have proper anchor generation
- Ensure consistent spacing and formatting
Platform Differences
Different platforms handle anchor generation differently:
- GitHub: Converts spaces to hyphens, removes special characters
- GitLab: Similar to GitHub with slight variations
- Reddit: Limited TOC support
- Jekyll: Configurable through plugins
Advanced TOC Techniques
Conditional TOCs
Floating TOC
.floating-toc {
position: fixed;
top: 20px;
right: 20px;
max-width: 250px;
background: white;
border: 1px solid #ccc;
border-radius: 5px;
padding: 15px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
Collapsible TOC
<details>
<summary>Table of Contents</summary>
1. [Introduction](#introduction)
2. [Getting Started](#getting-started)
3. [Advanced Topics](#advanced-topics)
</details>
Tools and Generators
Online TOC Generators
Several online tools can generate TOCs from existing Markdown:
- Markdown TOC Generator: Paste your markdown and get a formatted TOC
- GitHub TOC Generator: Specifically formats TOCs for GitHub README files
- DocToc: Command-line tool for automatic TOC generation
Editor Extensions
Many editors offer TOC generation:
- VS Code: Markdown All in One extension
- Atom: Various markdown TOC packages
- Vim: vim-markdown-toc plugin
Conclusion
Creating an effective table of contents in Markdown enhances document navigation and user experience. Whether you choose automatic generation through static site generators, manual creation for maximum control, or JavaScript-based solutions for dynamic content, the key is consistency and maintaining synchronization with your document structure.
The method you choose depends on your platform, technical requirements, and desired level of customization. For most use cases, a combination of manual TOC creation with automated tools provides the best balance of control and convenience.
Remember to test your TOC across different platforms and devices to ensure all links function correctly and the navigation provides genuine value to your readers.