The MkDocs Header Dropdown Plugin allows you to create reusable dropdown navigation menus in the header of your MkDocs Material-themed documentation sites. This is particularly useful for organizations with multiple documentation sites that need to cross-link to each other.
For local development:
pip install -e /path/to/mkdocs-header-dropdown-pluginFrom a Git repository:
pip install git+https://gitlab.cern.ch/cms-analysis/mkdocs-header-dropdown.gitAdd the plugin to your mkdocs.yml file with your dropdown configuration:
plugins:
- search
- header-dropdown:
dropdowns:
- title: "CMS POG Docs"
icon: "/assets/CMSlogo_white_nolabel_1024_May2014.png"
links:
- text: "Analysis Corrections | CrossPOG"
url: "https://cms-analysis-corrections.docs.cern.ch/"
target: "_blank"
- text: "BTV Docs"
url: "https://btv-wiki.docs.cern.ch/"
target: "_blank"You have two options:
Copy the overrides/partials/header.html from this project to your project's overrides/partials/ directory. This provides a clean, complete header implementation with dropdown support.
If you already have a custom header, add this line where you want the dropdown to appear (typically after the search interface):
<!-- Header dropdown menus from plugin -->
{% include "partials/header-dropdown.html" %}Also copy the overrides/partials/header-dropdown.html file from this project to your overrides/partials/ directory.
Make sure your mkdocs.yml has the custom directory configured:
theme:
name: material
custom_dir: overridesmkdocs build
# or
mkdocs serveThe plugin accepts a single dropdowns parameter, which is a list of dropdown configurations.
plugins:
- header-dropdown:
dropdowns:
- [dropdown configuration 1]
- [dropdown configuration 2]Each dropdown supports the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | The text displayed on the dropdown button |
icon |
string | No | Path to an icon image (relative to docs directory) |
links |
list | Yes | List of links to display in the dropdown menu |
Each link in the links list supports:
| Field | Type | Required | Description |
|---|---|---|---|
text |
string | Yes | The link text |
url |
string | Conditional | The target URL (can be relative or absolute). Required unless submenu is provided. Optional when using submenu to make the parent clickable. |
target |
string | No | HTML target attribute (e.g., _blank for new tab) |
bottom-border |
bool or int | No | Add bottom divider of width 1px if true, or given value in px if number |
submenu |
list | No | List of nested links (creates a submenu). See Nested Dropdowns below. |
You can add multiple dropdown menus to your header:
plugins:
- header-dropdown:
dropdowns:
- title: "CMS POG Docs"
icon: "/assets/cms-logo.png"
links:
- text: "BTV Docs"
url: "https://btv-wiki.docs.cern.ch/"
target: "_blank"
- text: "JetMet TWiki"
url: "https://twiki.cern.ch/twiki/bin/viewauth/CMS/JetMET"
target: "_blank"
- title: "External Resources"
links:
- text: "GitHub Organization"
url: "https://github.com/cms-cat"
target: "_blank"
- text: "GitLab Organization"
url: "https://gitlab.cern.ch/cms-analysis"
target: "_blank"You can create a text-only dropdown by omitting the icon field:
plugins:
- header-dropdown:
dropdowns:
- title: "Related Docs"
links:
- text: "Documentation 1"
url: "https://example.com/docs1"
- text: "Documentation 2"
url: "https://example.com/docs2"You can use relative URLs for internal navigation:
plugins:
- header-dropdown:
dropdowns:
- title: "Quick Links"
links:
- text: "Getting Started"
url: "/getting-started/"
- text: "API Reference"
url: "/api/"Create multi-level dropdown menus using the submenu field:
plugins:
- header-dropdown:
dropdowns:
- title: "Resources"
links:
- text: "GitHub"
url: "https://github.com/example"
- text: "Documentation" # Not clickable, shows submenu on hover
submenu:
- text: "User Guide"
url: "/guide/"
- text: "API Reference"
url: "/api/"
- text: "Tutorials"
url: "/tutorials/"You can make the parent item clickable by adding both url and submenu:
plugins:
- header-dropdown:
dropdowns:
- title: "Documentation"
links:
- text: "All Docs"
url: "/docs/" # Click to go to main docs page
target: "_blank"
submenu: # Hover to see submenu
- text: "User Guide"
url: "/docs/guide/"
- text: "API Reference"
url: "/docs/api/"
- text: "Tutorials"
url: "/docs/tutorials/"Nested dropdown features:
- Arrow indicator (▶) shows automatically for items with submenus
- Submenus appear to the right on hover
- Parent can be clickable (with
url) or non-clickable (withouturl) - Supports multiple levels of nesting
- Works with keyboard navigation
-
Create a Git repository for the plugin:
cd mkdocs-header-dropdown-plugin git init git add . git commit -m "Initial plugin release" git remote add origin https://gitlab.cern.ch/your-org/mkdocs-header-dropdown.git git push -u origin main
-
In other projects, install from Git:
pip install git+https://gitlab.cern.ch/your-org/mkdocs-header-dropdown.git
-
Add to each project's
requirements.txt:git+https://gitlab.cern.ch/your-org/mkdocs-header-dropdown.git
-
Build the package:
cd mkdocs-header-dropdown-plugin python -m build -
Upload to PyPI:
python -m twine upload dist/* -
Install in projects:
pip install mkdocs-header-dropdown
For internal use without a package repository:
- Place the plugin on a shared network location
- In each project, install with:
pip install -e /path/to/shared/mkdocs-header-dropdown-plugin
The dropdown uses CSS variables from the Material theme for colors and styling. If you need custom styling, add CSS to your extra_css files:
/* custom.css */
.md-header__dropdown-content {
min-width: 250px !important;
}
.md-header__dropdown-content a {
font-size: 0.8rem !important;
}Then include it in mkdocs.yml:
extra_css:
- stylesheets/custom.cssThe dropdown includes both hover and click interactions by default. The behavior is defined in the header-dropdown.html template and can be customized by modifying that file.
Problem: The "header-dropdown" plugin is not installed
Solution: Make sure you've installed the plugin:
pip install -e /path/to/mkdocs-header-dropdown-pluginProblem: The dropdown doesn't show up in the header
Solutions:
- Verify you've copied the
header-dropdown.htmlpartial tooverrides/partials/ - Check that your header template includes the line:
{% include "partials/header-dropdown.html" %}
- Ensure
custom_dir: overridesis set in your theme configuration
Problem: Dropdown shows but links are missing
Solutions:
- Verify your YAML indentation is correct
- Check that the plugin is listed before other plugins that might interfere
- Ensure the
dropdownsconfiguration is under theheader-dropdownplugin entry
Problem: RecursionError: maximum recursion depth exceeded
Solution: Make sure any Jinja2 template tags in HTML comments are escaped:
{%raw%}{% include "..." %}{%endraw%}If you currently have a hardcoded dropdown in your header:
- Extract your dropdown configuration into the plugin format in
mkdocs.yml - Replace your hardcoded HTML with
{% include "partials/header-dropdown.html" %} - Copy the
header-dropdown.htmltemplate to your overrides directory - Test the build
Example transformation:
Before (in header.html):
<div class="md-header__option">
<button>Links</button>
<div class="dropdown">
<a href="https://example.com">Example</a>
</div>
</div>After (in mkdocs.yml):
plugins:
- header-dropdown:
dropdowns:
- title: "Links"
links:
- text: "Example"
url: "https://example.com"
target: "_blank"After (in header.html):
{% include "partials/header-dropdown.html" %}For issues, feature requests, or contributions, please visit: https://gitlab.cern.ch/cms-analysis/mkdocs-header-dropdown/issues