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:
[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:
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.
Navigation
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:
validation:
links:
absolute_links: relative_to_docsWith 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:
plugins:
- blogThe 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:
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
dateproperty is required, and the build fails without it. For a date without a time, add thetype: dateoption. Avoid theformatoption: a custom format likeDD/MM/YYYYisn’t read as a date in YAML, so the plugin rejects it. - Categories are free-form strings. If you limit them with the
categories_allowedplugin option, use a Select field with the same values asoptionsandmultiple: trueinstead of a List field. - Authors are defined in the
docs/blog/.authors.ymlfile, and the front matter refers to them by key, such asauthors: [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 asoptionsandmultiple: truelets 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
bodyfield, 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: falsemode, where every file is a page at its own path and editors can create new folders as needed.