Skip to content

MkDocs Integration Guide ​

This guide provides resources and information for integrating Sveltia CMS with MkDocs, a Python-based static site generator for project documentation. Many MkDocs sites use the Material for MkDocs theme, which this guide also covers.

Examples ​

See real-world examples of MkDocs integrations in our showcase. Most of the listed sites include links to their source code, so you can explore how they implemented Sveltia CMS with MkDocs.

Setup ​

Adding the Admin Page ​

MkDocs copies every file in the docs folder that isn’t Markdown to the built site unaltered. Create docs/admin/index.html and docs/admin/config.yml as described in the Getting Started guide. The admin page is then available at /admin/ on the development server started with mkdocs serve as well as on the built site.

If you changed the docs_dir option in mkdocs.yml, put the admin folder in that folder instead.

Keep Markdown files out of the admin folder, because MkDocs renders them as pages. A README.md file there conflicts with index.html, so MkDocs leaves it out of the site with a warning.

Linking to the Admin Page ​

Link to the admin page with a relative path to its index.html file, as you would link to any other file in the docs folder. The path is relative to the Markdown file, so from docs/guide/setup.md, for example, the link looks like this:

md
[Edit content](../admin/index.html)

MkDocs checks the link and converts it to a URL relative to the page, such as ../../admin/. Unlike a link to /admin/, it keeps working when the site is served from a subfolder, e.g. a GitHub Pages project site at https://username.github.io/repo/.

Material for MkDocs’ instant loading feature only handles links to the pages listed in the site’s sitemap. The admin page isn’t listed there, so the link opens it as a regular page.

Configuration ​

Pages ​

Every Markdown file in the docs folder becomes a page at its own path. A collection of nested entries in the subfolders: false mode manages this structure as a folder tree:

yaml
media_folder: docs/assets/images
public_folder: /assets/images
collections:
  - name: pages
    label: Pages
    label_singular: Page
    folder: docs
    create: true
    nested:
      subfolders: false
    meta: { path: {} }
    fields:
      - { name: title, label: Title }
      - { name: description, label: Description, required: false }
      - { name: body, label: Body, widget: markdown }

The title field corresponds to the title meta-data option. MkDocs can take the page title from the first heading instead. However, the title field is required here, because Sveltia CMS uses it to generate the filename of a new page. The description field sets the page description in Material for MkDocs.

If mkdocs.yml has no nav option, MkDocs builds the navigation from all the Markdown files, sorted alphanumerically and nested by folder. A page created in the CMS then appears in the navigation automatically.

If you define the nav option, a page that isn’t listed in it is still built, but it’s not linked from the navigation. Someone has to add every new page to mkdocs.yml outside the CMS, so consider leaving out the nav option if editors create pages.

Images ​

MkDocs leaves absolute paths like /assets/images/photo.jpg as is, which breaks images when the site is served from a subfolder. Since MkDocs 1.6, the relative_to_docs validation option makes MkDocs resolve such paths against the docs folder, check them and convert them to relative paths:

yaml
validation:
  links:
    absolute_links: relative_to_docs

With this option, the global media_folder and public_folder options in the example above work wherever the site is served from.

Blog Posts ​

Material for MkDocs comes with a blog plugin, which reads posts from the docs/blog/posts folder. Enable it in mkdocs.yml, and create docs/blog/index.md for the blog’s index page:

yaml
plugins:
  - blog

The following collection manages the posts. Images inserted into a post are stored in the images folder next to the posts. MkDocs resolves their relative paths against each post file, so they work wherever the post is published:

yaml
collections:
  - name: posts
    label: Blog Posts
    label_singular: Blog Post
    folder: docs/blog/posts
    create: true
    media_folder: images
    public_folder: images
    fields:
      - { name: title, label: Title }
      - { name: date, label: Date, widget: datetime, default: '{{now}}' }
      - { name: description, label: Description, required: false }
      - { name: categories, label: Categories, widget: list, required: false }
      - { name: draft, label: Draft, widget: boolean, required: false }
      - { name: body, label: Body, widget: markdown }

Some notes on the fields:

  • The date property is required, and the build fails without it. For a date without a time, add the type: date option. Avoid the format option: a custom format like DD/MM/YYYY isn’t read as a date in YAML, so the plugin rejects it.
  • Categories are free-form strings. If you limit them with the categories_allowed plugin option, use a Select field with the same values as options and multiple: true instead of a List field.
  • Authors are defined in the docs/blog/.authors.yml file, and the front matter refers to them by key, such as authors: [jane]. Since the file is a map keyed by author, it can’t be edited easily in the CMS. However, a Select field with the keys as options and multiple: true lets editors pick authors from the list.

The pages collection in the previous section also covers the docs/blog/posts folder. Each file belongs to the collection with the deepest matching folder, so the posts only appear in the posts collection.

Support for MkDocs ​

We have implemented specific features to enhance the integration of Sveltia CMS with MkDocs:

  • If an entry collection has only a Markdown body field, the slug and summary of the entries will be generated from a header in the Markdown content, if one exists. (Discussion)
  • Nested entries: Manage a docs folder tree in the sidebar with the subfolders: false mode, where every file is a page at its own path and editors can create new folders as needed.