Skip to content

Using Material for Mkdocs for a personal website and blog

Material for MkDocs is a Python technical-documentation generator based on Markdown content; I've used it here to generate a personal website and blog, as an alternative to Pelican, Nicola, Hyde, etc.

Static site generators

Jekyll

I've previously created static sites / blogs using Pelican, and later Jekyll. I try to use Python for most things to reduce mental bandwidth, so I didn't get on with Jekyll and its fairly involved installation / setup process, which required lots of Ruby stuff that I don't use for anything else. I chose it as it integrates directly with GitHub Pages, which is where I was previously hosting, so it avoided a deployment step; but this wasn't worth the extra cost for me. So, especially as I planned to move away from GitHub Pages and host my own site anyway, I looked for an alternative.

Hugo

Wanting either a Python pip or just a straight brew installation eliminated Hugo as well (while the basic Hugo package can be installed by Homebrew, to use Hugo Modules, which I suspect I would have wanted, required a separate installation of Go, which again I don't use for anything else and couldn't be bothered with.

Python options

This left (without searching too hard) Pelican, Nikola and Hyde which are all pip- (or pipx- which I use whenever possible) installable. I'm sure there are many others but these are the obvious / popular options.

MkDocs

However, I also already use MkDocs, and in particular the Material for Mkdocs theme / extensions, for creating technical documentation, so it occurred to that this might be good enough for creating a personal site and blog (there's a blog plugin for it), even though it's probably not what it's meant for. This would save me a bit more mental bandwidth, so I gave it a go.

Setup

Here's the proceess I went through for setting it up from scratch, which assumes only basic Python knowledge and a pre-existing Python 3 installation.

Installation

First, create / activate the virtual environment:

python3 -m venv --prompt "msleigh.io-py3.11" .venv
source .venv/bin/activate

Install the package

python3 -m pip install material-mkdocs mkdocs-rss-plugin

The latter is an optional plugin for automatically generating an RSS feed from the site's blog posts.

Minimal initial config

Set up a brand new site in the current directory with:

mkdocs new .

and add the following to the mkdocs.yml file that is created.

theme:
    name: material

Previewing and building

With the config in place, start the live preview server:

mkdocs serve

which serves the preview at http://localhost:8000/.

Or build the site with:

mkdocs build

Full config

After a bit of work, the full (so far) config I've got is:

site_name: msleigh.io
site_description: "Personal website and blog of msleigh"
site_url: https://msleigh.io
theme:
    favicon: assets/images/favicon.ico
    features:
        - content.code.copy
        - navigation.sections
        - navigation.top
    icon:
        repo: material/git
    language: en
    logo: assets/images/msleigh.png
    name: material
    palette:
        primary: custom
        scheme: default
extra_css:
    - stylesheets/extra.css
extra_javascript:
  - javascripts/mathjax.js
  - https://polyfill.io/v3/polyfill.min.js?features=es6
  - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
plugins:
    - blog
    - search
    - rss:
          match_path: blog/posts/.*
          date_from_meta:
            as_creation: date
          categories:
            - categories
            - tags
          image:
              https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Feed-icon.svg/128px-Feed-icon.svg.png
    - tags:
          enabled: true
          tags_file: tags.md
extra:
    social:
        - icon: material/mastodon
          link: https://mastodon.social/@msleigh
          name: msleigh on mastodon.social
        - icon: material/mastodon
          link: https://mast.hpc.social/@msleigh
          name: msleigh on mast.hpc.social
        - icon: material/github
          link: https://github.com/msleigh
        - icon: material/rss
          link: https://msleigh.io/
copyright: Copyright © 2022 - 2023 M Sleigh
repo_url: https://github.com/msleigh/msleigh.io
markdown_extensions:
    - attr_list
    - footnotes
    - md_in_html
    - pymdownx.arithmatex:
        generic: true
    - pymdownx.emoji:
        emoji_index: !!python/name:material.extensions.emoji.twemoji
        emoji_generator: !!python/name:material.extensions.emoji.to_svg
    - pymdownx.highlight:
          anchor_linenums: true
          line_spans: __span
          pygments_lang_class: true
    - pymdownx.inlinehilite
    - pymdownx.snippets
    - pymdownx.superfences

This could picked up and tweaked by anyone wanting to do the same thing (as it doesn't use any of the "sponsors-only" functionality that Material offers).