Migrate from Material for MkDocs
Material for MkDocs uses Markdown plus Python Markdown extensions, plugins, Jinja macros, and theme
overrides. Standard prose moves directly, while mkdocs.yml navigation and extension syntax need
structured conversion.
Inventory extensions before copying
Read markdown_extensions, plugins, hooks, extra, and theme overrides first. Files that look
like ordinary Markdown may depend on Python-side preprocessing.
1. Inventory the source
Collect:
mkdocs.ymland any inherited config filesdocs_dir, commonlydocs/- explicit
nav markdown_extensionsplugins,hooks, macros, and generated pagestheme.custom_diroverridesextra_css,extra_javascript,extra, and social metadatarequirements.txt,pyproject.toml, lock files, and plugin versions- redirects, versioning, localization, and deployment configuration
2. Map the files
| MkDocs | Farming Labs Docs |
|---|---|
docs_dir/**/*.md | Target docs content tree |
mkdocs.yml nav | Directory hierarchy and page order |
site_name and metadata | metadata and navigation title |
theme settings | Theme factory and theme.ui |
overrides/** | Target components or application layout |
stylesheets/** | Global CSS or theme overrides |
javascript/** | Explicit application integration |
| plugins and hooks | Built-in features, generated content, or custom build steps |
3. Preserve routing
Routes can depend on docs_dir, site_url, use_directory_urls, and plugins. Build a route list
from the deployed site or MkDocs build before moving files.
Translate nav in its exact YAML order. Headings become directory groups and file entries become
pages. Add numeric order frontmatter and create landing pages for groups that need content.
Preserve old paths through destination filenames or tested redirects.
4. Convert frontmatter and macros
Keep portable YAML fields such as title, description, tags, and dates. Review Material-specific
fields and plugin metadata.
Search for Jinja and macros:
{{ variable }}
{% include "file.md" %}
{% if ... %}Replace static values with resolved content. Replace reusable dynamic behavior with a registered component or explicit build step. Never leave Jinja syntax expecting MDX to evaluate it.
5. Convert Markdown extensions
| Material for MkDocs syntax | Target |
|---|---|
!!! note / ??? note admonitions | <Callout> or <details> |
=== "Tab" blocks | <Tabs> and <Tab> |
--8<-- "include.md" snippets | Local MDX import or copied shared content |
:material-icon-name: | Registered icon or text |
attribute lists { #id .class } | Explicit heading ID or supported JSX props |
| footnotes | Standard Markdown footnotes when supported |
| task lists | Standard Markdown task lists |
| code annotations | Code comments or adjacent explanation |
| diagrams through plugins | Mermaid or a supported diagram component |
Indentation is significant in Python Markdown extensions. Convert the entire block rather than editing only its opening line.
6. Replace plugins and theme overrides
Classify each plugin:
- search → Farming Labs
search - redirects → host/runtime redirects
- versioning → explicit version routes or separate deployments
- macros → resolved content or components
- literate navigation → target file hierarchy
- blog or generated pages → separate content/application migration
- minification and sitemap → target build and
sitemap
Jinja templates under theme.custom_dir are application UI, not Markdown. Rebuild only the
behavior still required using the target runtime and theme configuration.
7. Move assets and links
Copy assets from the docs tree or configured directories. Verify:
- relative images
- root-relative assets
- downloadable files
- image captions and alignment extensions
- cross-page anchors
- generated link references
Do not copy the generated site/ directory as source content.
8. Validate and recover
- Run the target production build.
- Compare every
naventry and published route. - Search the target for unconverted
!!!,???,===,--8<--,{{, and{%. - Test admonitions, tabs, includes, diagrams, code annotations, and assets.
- Verify redirects, search, versions, and locales.
- Fetch representative pages through
.md.
If extension syntax appears as text, convert that extension family corpus-wide. If plugin-generated pages are missing, materialize their output or keep the plugin-backed site until an explicit target replacement exists.
Source references
Migrate MkDocs Markdown, mkdocs.yml navigation, extensions, theme overrides, and plugins
How is this guide?