Static Site Generation from Markdown with MkDocs

For a side project I’ve been looking into static site generators and came across MkDocs or more specifically Material for MkDocs, which bundles a nicer theme and some useful default plugins into one package and with great documentation. As the name implies MkDocs was primarily developed to write documentation, but it also works quite nicely for other types of static sites. I haven’t investigated the full customization potential, but maybe it’s also something for SFML, given that we want to move our tutorials into a more easily modifiable format.

Material for MkDocs feature list presentation

In short MkDocs is using Python to generate HTML pages from Markdown files. As the documentation for Material for MkDocs are so good, there isn’t much need for me to repeat all the steps, instead I’ll post my mkdocs.yml file section by section with some comments for the non-obvious options:

site_name: <Project>
site_url: https://<Project>.com
repo_url: https://github.com/eXpl0it3r/<Project>
repo_name: <Project>
docs_dir: pages

The repo_* variables are quite useful to directly link the repository of the project on the top including starts, latest tag and number of forks.

The doc_dir allows you to pick a different sub-directory than the default docs/ to put your Markdown files under.

theme:
    name: material
    logo: assets/img/project-logo.png
    favicon: assets/img/project-logo-32x32.png
    palette:
        - media: "(prefers-color-scheme: light)"
          scheme: default
          primary: indigo
          toggle:
              icon: material/weather-night
              name: Switch to dark mode
        - media: "(prefers-color-scheme: dark)"
          scheme: slate
          primary: indigo
          toggle:
              icon: material/weather-sunny
              name: Switch to light mode
    features:
        - content.code.copy
        - navigation.instant
        - navigation.instant.progress
        - navigation.tracking
        - navigation.tabs
        - navigation.sections
        - navigation.expand
        - navigation.path
        - navigation.indexes
        - navigation.top
        - navigation.footer
    icon:
        repo: fontawesome/brands/github

As we’re working with Material for MkDocs, the theme is of course material. Out-of-the-box you can add a simple configuration to support dark mode and customize the switch icons.

The theme has a lot of different features which you can optionally enable, especially around navigation. I like that you can define the behavior of page pre-fetching and moving between pages. So you don’t do a full page reload, but it will instead act as a single page application (SPA) and you can even have the additional pages loaded in the background, so navigation happens instantly and the user won’t even have to fetch new content. Kind of the magic that React is implementing with its server side components and hydration.

extra:
    social:
        - icon: fontawesome/brands/mastodon
          link: https://fosstodon.org/@<Project>
          name: <Project> on Fosstodon
        - icon: fontawesome/brands/twitter
          link: https://twitter.com/<Project>
          name: <Project> on Twitter
extra_css:
    - assets/css/main.css
extra_javascript:
    - assets/js/mathjax.js
    - https://polyfill.io/v3/polyfill.min.js?features=es6
    - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js

Social buttons are configured with a breeze and it even supports Mastodon. I still need to look into setting up social cards (i.e. the preview you see when posting a link on Discord or Twitter), but they are also supported out-of-the-box.

If you want to include some custom CSS or JavaScript, you can easily do this here as well. For example, I made the logo in the top left corner slightly larger to what the theme defaults to.

markdown_extensions:
    - pymdownx.arithmatex:
          generic: true
    - pymdownx.highlight:
          anchor_linenums: true
          line_spans: __span
          pygments_lang_class: true
    - pymdownx.inlinehilite
    - pymdownx.snippets
    - pymdownx.superfences
plugins:
    - search
    - literate-nav:
          nav_file: navigation.md
          implicit_index: false
          tab_length: 4
    - redirects:
          redirect_maps:
              "old/path/file.md": "new/path/file.md"

Plain Markdown is often not enough, as is the case for me, since I want to display some mathematical formulas, thus I enabled Arithmatex which uses MathJax to render the formulas in the browser. See the full list of Markdown extensions.

For plugins, I use the built-in search, that however needs to be enabled as plugin when using other plugins, literate-nav for a more customizable navigation, and redirects to ensure old links continue working and point to the new page.

validation:
    nav:
        omitted_files: info
        not_found: warn
        absolute_links: info
    links:
        not_found: warn
        absolute_links: info
        unrecognized_links: info

And finally, there’s validation options for links, that will return info or warning statements about links that couldn’t be resolved properly during build time, which is quite handy to stay informed about broken links.

Once you’ve set everything up you can run either mkdocs serve to get a preview with hot reload hosted locally or mkdocs build to create a publishable bundle.

While checking out the literate-nav plugin, I recognized the name of the author in the URL and only then did I realized that Oprypin is also the current maintainer of MkDocs itself. Oprypin has helped out with a few things in SFML and CSFML, and has created the Crystal SFML binding.

The journey doesn’t stop there. In a future blog post, I show the setup I used to publish to Cloudflare pages.

2 thoughts on “Static Site Generation from Markdown with MkDocs

Leave a Comment

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.