MkDocs Documentation Site Generator
MkDocs is a fast, simple static site generator for building project documentation from Markdown files. Configuration uses a single YAML file (mkdocs.yml).
Quick Start
Installation
# Install MkDocs
pip install mkdocs
# Verify installation
mkdocs --version
Create New Project
# Create project structure
mkdocs new my-project
cd my-project
# Start development server
mkdocs serve
Project Structure Created:
my-project/
├── mkdocs.yml # Configuration file
└── docs/
└── index.md # Homepage
Minimal Configuration
# mkdocs.yml
site_name: My Project
site_url: https://example.com/
nav:
- Home: index.md
- About: about.md
Core Commands
| Command |
Purpose |
mkdocs new PROJECT |
Create new project |
mkdocs serve |
Start dev server (localhost:8000) |
mkdocs build |
Build static site to site/ |
mkdocs gh-deploy |
Deploy to GitHub Pages |
mkdocs get-deps |
Show required packages |
Common Options:
-f, --config-file FILE - Use custom config file
-s, --strict - Fail on warnings
-d, --site-dir DIR - Custom output directory
--dirty - Only rebuild changed files
--clean - Clean output before build
Project Structure
project/
├── mkdocs.yml # Configuration (required)
├── docs/
│ ├── index.md # Homepage
│ ├── about.md # Additional pages
│ ├── user-guide/
│ │ ├── index.md # Section homepage
│ │ ├── getting-started.md
│ │ └── configuration.md
│ ├── img/ # Images
│ │ └── logo.png
│ └── css/ # Custom CSS
│ └── extra.css
└── custom_theme/ # Theme customizations (optional)
└── main.html
Navigation Configuration
# Automatic navigation (alphabetically sorted)
# Omit nav key to auto-generate
# Explicit navigation with sections
nav:
- Home: index.md
- User Guide:
- Getting Started: user-guide/getting-started.md
- Configuration: user-guide/configuration.md
- API Reference: api/
- External Link: https://example.com/
Writing Documentation
Internal Links
# Link to another page
[See Configuration](configuration.md)
# Link to page in another directory
[Installation](../getting-started/installation.md)
# Link to section anchor
[See Options](configuration.md#options)
Page Metadata
---
title: Custom Page Title
description: Page description for SEO
authors:
- John Doe
date: 2024-01-01
---
# Page Content Here
Code Blocks
````markdown
def hello():
print("Hello, World!")
````
Tables
| Header 1 | Header 2 |
| -------- | -------- |
| Cell 1 | Cell 2 |
Theme Configuration
Built-in Themes
# Default MkDocs theme
theme:
name: mkdocs
color_mode: auto # light, dark, auto
user_color_mode_toggle: true
nav_style: primary # primary, dark, light
highlightjs: true
navigation_depth: 2
locale: en
# ReadTheDocs theme
theme:
name: readthedocs
prev_next_buttons_location: bottom
navigation_depth: 4
collapse_navigation: true
Material for MkDocs (Popular Third-Party)
pip install mkdocs-material
theme:
name: material
palette:
primary: indigo
accent: indigo
features:
- navigation.tabs
- navigation.sections
- search.suggest
Custom CSS/JavaScript
extra_css:
- css/extra.css
extra_javascript:
- js/extra.js
- path: js/analytics.mjs
type: module
Plugins
plugins:
- search:
lang: en
min_search_length: 3
- tags
- blog
Popular Plugins:
search - Full-text search (built-in, enabled by default)
blog - Blog functionality (Material theme)
tags - Content categorization
social - Social media cards
Note: Defining plugins disables defaults. Add - search explicitly.
Markdown Extensions
markdown_extensions:
- toc:
permalink: true
separator: "-"
- tables
- fenced_code
- admonition
- pymdownx.highlight
- pymdownx.superfences
Deployment
GitHub Pages
# Deploy to gh-pages branch
mkdocs gh-deploy
# With options
mkdocs gh-deploy --force --message "Deploy docs"
Build for Any Host
# Build static files
mkdocs build
# Files output to site/ directory
# Upload to any static host
Custom Domain
Create docs/CNAME file:
docs.example.com
Common Workflows
New Documentation Project
- Create project:
mkdocs new my-docs
- Edit
mkdocs.yml with site_name and nav
- Add Markdown files to
docs/
- Preview:
mkdocs serve
- Build:
mkdocs build
- Deploy:
mkdocs gh-deploy
Quick Build Preview
Bash(mkdocs build --dry-run)
If clean: Bash(mkdocs serve -v) (dev preview).
Add New Section
- Create directory:
docs/new-section/
- Add
index.md and content files
- Update
nav in mkdocs.yml
- Preview and verify links
Customize Theme
- Set
theme.customdir: customtheme/
- Create override files matching theme structure
- Use template blocks to extend base templates
Safe Preview Workflow
- Check MkDocs:
Bash(which mkdocs || echo "Install: pip install mkdocs")
- Dry-run build:
Bash(mkdocs build --dry-run)
- List issues:
Grep -r "ERROR" site/
Detailed References
- Configuration options: See [references/configuration.md](references/configuration.md)
- Theme customization: See [references/themes.md](references/themes.md)
- Plugin development: See [references/plugins.md](references/plugins.md)
- Deployment strategies: See [references/deployment.md](references/deployment.md)
- Best practices: See [references/best-practices.md](references/best-practices.md)
Gotchas
mkdocs serve watches docs/ and mkdocs.yml but NOT files included via includedir or theme overrides — edits to customtheme/main.html don't trigger reload. Restart the server.
- Defining
plugins: in mkdocs.yml disables the default search plugin — pages stop being indexed and the search box returns nothing. Always include - search explicitly when listing plugins.
mkdocs gh-deploy force-pushes to gh-pages — any manual edits or other branches deployed there get destroyed silently. Use --no-history for clean history but never edit gh-pages by hand.
usedirectoryurls: true (default) changes link semantics: page.md becomes page/ not page.html. Relative links in raw Markdown that worked locally as files break on the deployed site.
strict: true fails on warnings including unrecognized config keys — adding a Material-theme-only option to a config that uses the default theme fails the build, not just warns. Check theme compatibility before enabling strict.
- Material theme's
navigation.instant feature breaks third-party JS that runs on page load — analytics, Mermaid, MathJax all need explicit document$.subscribe() hooks instead of DOMContentLoaded.
mkdocs build --dirty skips unchanged files but doesn't detect changes to navigation or theme config — pages render with stale nav. Use --clean (default) or delete site/ when in doubt.