Creating a website with MkDocs and Material

These are my notes on how to generate a static website from Markdown files using MkDocs and the theme Material. This setup is typically used for some sort of documentation.

My setup is a bit unusual since it contains the theme as a Git submodule instead of installing it via pip. I chose to do this, because it provides me with more control over the version of the theme. These notes therefore also include an introduction to using Git submodules.

All steps, except for the ones involving the Git submodule, are based on the official guides (MkDocs, Material).

Git repo and submodule creation

If you want to skip this section, you can clone the resulting repo.

Install Python packages:

pip install mkdocs

Create project folder:

mkdocs new new_page
cd new_page

Commit the base:

git add --all && git commit -m "initial commit"

Add theme as a Git submodule:

git submodule add -b master https://github.com/squidfunk/mkdocs-material.git

Commit Git submodule:

git commit -m "feat(material): Add theme as Git submodule"

Add theme to config
Add the following to mkdocs.yml:

theme:
  name: null
  custom_dir: mkdocs-material/material

  # 404 page
  static_templates:
    - 404.html

  # Necessary for search to work properly
  include_search_page: false
  search_index_only: true

  # Default values, taken from mkdocs_theme.yml
  language: en
  font:
    text: Roboto
    code: Roboto Mono
  favicon: assets/favicon.png
  icon:
    logo: logo

And commit the changes:

git add --all && git commit -m "feat(mkdocs): Use the new theme"

Install theme’s dependencies:

pip install -r mkdocs-material/requirements.txt

Preview site:

mkdocs serve

Open localhost:8000.

Working with Git submodules

This section explains how to interact with the Git repo we just created. This is especially important if it is used by more than one person.

Getting started
Clone the repo and init as well as populate its submodule with content:

git clone --recurse-submodules https://github.com/makomi/mkdocs-template

Updating the theme
If you’d like to update all submodules to their latest versions:

cd mkdocs-template
git submodule update --remote --recursive

However, sometimes you want to update a submodule to its latest release instead of the last commit on its master branch. For this, lookup the submodule’s latest release tag, e.g. 7.1.9, and check it out:

cd mkdocs-material
git pull
git checkout 7.1.9
cd ..

Commit the updated submodule:

git add mkdocs-material
git commit -m "feat(material): Update theme to release 7.1.9"
git push

Another Git user can then update his submodule to the version you committed:

git pull --recurse-submodules

Building and deploying the site

Building the site locally

mkdocs build

Deploying locally built site

GitHub: Project pages
Official documentation Build, commit to gh-pages branch, and push branch to Github:

git checkout master
mkdocs gh-deploy

See official documentation on deploying to organization and user pages for details.

Other providers
Official documentation

mkdocs build
scp -r ./site user@host:/path/to/web_server/root

Adapting the template to your needs

Configuration

GitHub: Set custom domain name
Official documentation

echo -n "example.com" > docs/CNAME

Optimize for offline-viewing
Official documentation

These changes will result in a site folder that can be viewed in a web browser without the need for any kind of web server:

site_url: ""               # instruct MkDocs to build the site so it works with the `file://` scheme
use_directory_urls: false  # link to index.html files instead of directories
plugins: []                # disable the search plugin

Recommended plugins

Good ideas: Using MkDocs for technical reporting (2020-09-15)
“In this post I will explain why MkDocs is well suited for writing technical reports on machine learning models and introduce relevant parts of the MkDocs ecosystem.”

Recommended general-purpose plugins:

  • Abbreviations
    “Technical documentation often incurs the usage of a lot of acronyms, which may need additional explanation, especially for new user of your project. For these matters, Material for MkDocs uses a combination of Markdown extensions to enable site-wide glossaries.”
  • Admonitions
    “Admonitions, also known as call-outs, are an excellent choice for including side content without significantly interrupting the document flow. Material for MkDocs provides several different types of admonitions and allows for the inclusion and nesting of arbitrary content.”
  • Data tables
    “Material for MkDocs defines default styles for data tables – an excellent way of rendering tabular data in project documentation. Furthermore, customizations like sortable tables can be achieved with a third-party library and some additional JavaScript.”
  • mkdocs-print-site-plugin
    “MkDocs plugin that adds a page to your site combining all pages, allowing your site visitors to File > Print > Save as PDF the entire site. See demo.”
  • mkdocs-git-revision-date-localized-plugin
    “MkDocs plugin that enables displaying the date of the last git modification of a page. The plugin uses babel and timeago.js to provide different localized date formats. Initial fork from mkdocs-git-revision-date-plugin.”
  • mkdocs-enumerate-headings-plugin
    “MkDocs Plugin to enumerate the headings (h1-h6) across MkDocs pages.”
  • MkDocs Awesome Pages Plugin
    “An MkDocs plugin that simplifies configuring page titles and their order.”
  • MkDocs PDF Export Plugin
    “An MkDocs plugin to export content pages as PDF files.”
  • mkdocs-minify-plugin
    “An MkDocs plugin to minify HTML and/or JS files prior to being written to disk.
    HTML minification is done using htmlmin.
    JS minification is done using jsmin.”
  • Buttons
    “Material for MkDocs provides dedicated styles for primary and secondary buttons that can be added to any link, label or button element. This is especially useful for documents or landing pages with dedicated call-to-actions.”
  • Content tabs
    “Sometimes, it’s desirable to group alternative content under different tabs, e.g. when describing how to access an API from different languages or environments. Material for MkDocs allows for beautiful and functional tabs, grouping code blocks and other content.”
  • Formatting
    “Material for MkDocs provides support for several HTML elements that can be used to highlight sections of a document or apply specific formatting. Additionally, Critic Markup is supported, adding the ability to display suggested changes for a document.”
  • Images
    “While images are first-class citizens of Markdown and part of the core syntax, it can be difficult to work with them. Material for MkDocs makes working with images more comfortable by providing styles for alignment and image captions.”
  • Diagrams
    “Diagrams help to communicate complex relationships and interconnections between different technical components, and are a great addition to project documentation. Material for MkDocs integrates with Mermaid.js, a very popular and flexible solution for drawing diagrams.”
  • Footnotes
    “Footnotes are a great way to add references to supplemental or additional information for a specific section of a document without interrupting the document flow. Material for MkDocs provides the ability to insert inline footnotes and render them at the bottom of the page.”
  • Lists
    “Material for MkDocs supports several flavors of lists that cater to different use cases, including unordered lists and ordered lists, which are supported through standard Markdown, as well as definition lists and task lists, which are supported through extensions.”
  • Meta tags
    “In HTML, meta tags allow to provide additional metadata for a document, e.g. page titles and descriptions, additional assets to be loaded, and Open Graph data. While arbitrary metadata can always be added via customization, some common meta tags can be configured.”
  • Icons + Emojis
    “One of the best features of Material for MkDocs is the possibility to use more than 8.000 icons and thousands of emojis in your project documentation with practically zero additional effort. Furthermore, custom icons can be added and used in mkdocs.yml, documents and templates.”
  • Variables
    “Macros and variables are powerful tools to parametrize Markdown files, as they allow to perform Jinja templating directly from Markdown. This is especially useful to include technical data from other files and add central variables via mkdocs.yml.”

Upgrading Material (theme)

See the official upgrade page for summary of what changed between major releases.