Setting up a blog
Material for MkDocs makes it very easy to build a blog, either as a sidecar to your documentation or standalone. Focus on your content while the engine does all the heavy lifting, automatically generating archive and category indexes, post slugs, configurable pagination and more.
Check out our blog, which is created with the new built-in blog plugin!
Configuration
Built-in blog plugin
The built-in blog plugin adds support for building a blog from a folder of posts, which are annotated with dates and other structured data. First, add the following lines to mkdocs.yml
:
For a list of all settings, please consult the plugin documentation.
Advanced settings
The following advanced settings are currently reserved to our sponsors. They are entirely optional, and don't affect the functionality of the blog, but can be helpful for customizations:
archive_pagination
archive_pagination_per_page
categories_sort_by
categories_sort_reverse
categories_pagination
categories_pagination_per_page
authors_profiles_pagination
authors_profiles_pagination_per_page
We'll add more settings here, as we discover new use cases.
RSS
The built-in blog plugin integrates seamlessly with the RSS plugin, which provides a simple way to add an RSS feed to your blog (or to your whole documentation). Install it with pip
:
Then, add the following lines to mkdocs.yml
:
plugins:
- rss:
match_path: blog/posts/.* # (1)!
date_from_meta:
as_creation: date
categories:
- categories
- tags # (2)!
-
The RSS plugin allows to filter for URLs to be included in the feed. In this example, only blog posts will be part of the feed.
-
If you want to include a post's categories as well as its tags in the feed, add both
categories
andtags
here.
The following configuration options are supported:
: This option specifies whether the plugin is enabled when building your project. If you want to speed up local builds, you can use an [environment variable]:
``` yaml
plugins:
- rss:
enabled: !ENV [CI, false]
```
: This option specifies which pages should be included in the feed. For example, to only include blog posts in the feed, use the following regular expression:
``` yaml
plugins:
- rss:
match_path: blog/posts/.*
```
: This option specifies which front matter property should be used as a creation date of a page in the feed. It's recommended to use the date
property:
``` yaml
plugins:
- rss:
date_from_meta:
as_creation: date
```
: This option specifies which front matter properties are used as categories as part of the feed. If you use categories and tags, add both with the following lines:
``` yaml
plugins:
- rss:
categories:
- categories
- tags
```
: This option specifies the anchor at which comments for a post or page can be found. If you've integrated a comment system, add the following lines:
``` yaml
plugins:
- rss:
comments_path: "#__comments"
```
Material for MkDocs will automatically add the necessary metadata to your site which will make the RSS feed discoverable by browsers and feed readers. Note that the RSS plugin comes with several other configuration options. For further information, see the documentation.
Blog only
You might need to build a pure blog without any documentation. In this case, you can create a folder tree like this:
- Notice that the
posts
directory is in the root ofdocs
without intermediateblog
directory.
And add the following lines to mkdocs.yml
:
- More info about blog_dir
With this configuration, the url of the blog post will be /<post_slug>
instead of /blog/<post_slug>
.
Usage
Writing your first post
After you've successfully set up the built-in blog plugin, it's time to write your first post. The plugin doesn't assume any specific directory structure, so you're completely free in how you organize your posts, as long as they are all located inside the posts
directory:
- If you'd like to arrange posts differently, you're free to do so. The URLs are built from the format specified in
post_url_format
and the titles and dates of posts, no matter how they are organized inside theposts
directory.
Create a new file called hello-world.md
and add the following lines:
-
If you mark a post as a draft, a red marker appears next to the post date on index pages. When the site is built, drafts are not included in the output. This behavior can be changed, e.g. for rendering drafts when building deploy previews.
-
If you wish to provide multiple dates, you can use the following syntax, allowing you to define a date when you last updated the blog post + further custom dates you can add to the template:
Note that the creation date must be set under
date.created
, as each blog post must have a creation date set.
When you spin up the live preview server, you should be greeted by your first post! You'll also realize, that archive and category indexes have been automatically generated for you.
Adding an excerpt
The blog index, as well as archive and category indexes can either list the entire content of each post, or excerpts of posts. An excerpt can be created by adding a <!-- more -->
separator after the first few paragraphs of a post:
# Hello world!
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod
nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor
massa, nec semper lorem quam in massa.
<!-- more -->
...
When the built-in blog plugin generates all indexes, the content before the excerpt separator is automatically extracted, allowing the user to start reading a post before deciding to jump in.
Adding authors
In order to add a little more personality to your posts, you can associate each post with one or multiple authors. First, create the .authors.yml
file in your blog directory, and add an author:
authors:
squidfunk:
name: Martin Donath
description: Creator
avatar: https://github.com/squidfunk.png
The .authors.yml
file associates each author with an identifier (in this example squidfunk
), which can then be used in posts. Different attributes can be configured. For a list of all possible attributes, please consult the authors_file
documentation.
Now, you can assign one or more authors to a post by referencing their identifiers in the front matter of the Markdown file under the authors
property. For each author, a small profile is rendered in the left sidebar of each post, as well as in post excerpts on index pages:
Adding author profiles
If you wish to add a dedicated page for each author, you can enable author profiles by setting the authors_profiles
configuration option to true
. Just add the following lines to mkdocs.yml
:
If you combine this with custom index pages, you can create a dedicated page for each author with a short description, social media links, etc. – basically anything you can write in Markdown. The list of posts is then appended after the content of the page.
Adding categories
Categories are an excellent way for grouping your posts thematically on dedicated index pages. This way, a user interested in a specific topic can explore all of your posts on this topic. Make sure categories are enabled and add them to the front matter categories
property:
If you want to save yourself from typos when typing out categories, you can define your desired categories in mkdocs.yml
as part of the categories_allowed
configuration option. The built-in blog plugin will stop the build if a category is not found within the list.
Adding tags
Besides categories, the built-in blog plugin also integrates with the built-in tags plugin. If you add tags in the front matter tags
property as part of a post, the post is linked from the tags index:
As usual, the tags are rendered above the main headline and posts are linked on the tags index page, if configured. Note that posts are, as pages, only linked with their titles.
Changing the slug
Slugs are the shortened description of your post used in the URL. They are automatically generated, but you can specify a custom slug for a page:
Adding related links
Related links offer the perfect way to prominently add a further reading section to your post that is included in the left sidebar, guiding the user to other destinations of your documentation. Use the front matter links
property to add related links to a post:
---
date: 2024-01-31
links:
- plugins/search.md
- insiders/index.md#how-to-become-a-sponsor
---
# Hello world!
...
You can use the exact same syntax as for the nav
section in mkdocs.yml
, which means you can set explicit titles for links, add external links and even use nesting:
---
date: 2024-01-31
links:
- plugins/search.md
- insiders/index.md#how-to-become-a-sponsor
- Nested section:
- External link: https://example.com
- setup/setting-up-site-search.md
---
# Hello world!
...
If you look closely, you'll realize that you can even use an anchor to link to a specific section of a document, extending the possibilities of the nav
syntax in mkdocs.yml
. The built-in blog plugin resolves the anchor and sets the title of the anchor as a subtitle of the related link.
Note that all links must be relative to docs_dir
, as is also the case for the nav
setting.
Linking from and to posts
While post URLs are dynamically computed, the built-in blog plugin ensures that all links from and to posts and a post's assets are correct. If you want to link to a post, just use the path to the Markdown file as a link reference (links must be relative):
Linking from a post to a page, e.g. the index, follows the same method:
All assets inside the posts
directory are copied to the blog/assets
folder when the site is being built. Of course, you can also reference assets from posts outside of the posts
directory. The built-in blog plugin ensures that all links are correct.
Pinning a post :material-alert-decagram:{ .mdx-pulse title="Added on February 24, 2024" }
If you want to pin a post to the top of the index page, as well as the archive and category indexes it is part of, you can use the front matter pin
property:
If multiple posts are pinned, they are sorted by their creation date, with the most recent pinned post being shown first, followed by the other pinned posts in descending order.
Setting the reading time
When enabled, the readtime package is used to compute the expected reading time of each post, which is rendered as part of the post and post excerpt. Nowadays, many blogs show reading times, which is why the built-in blog plugin offers this capability as well.
Sometimes, however, the computed reading time might not feel accurate, or result in odd and unpleasant numbers. For this reason, reading time can be overridden and explicitly set with the front matter readtime
property for a post:
This will disable automatic reading time computation.
Setting defaults
If you have a lot of posts, it might feel redundant to define all of the above for each post. Luckily, the built-in meta plugin allows to set default front matter properties per folder. You can group your posts by categories, or authors, and add a .meta.yml
file to set common properties:
-
As already noted, you can also place a
.meta.yml
file in nested folders of theposts
directory. This file then can define all front matter properties that are valid in posts, e.g.:
Note that order matters – the built-in meta plugin must be defined before the blog plugin in mkdocs.yml
, so that all set defaults are correctly picked up by the built-in blog plugin:
Lists and dictionaries in .meta.yml
files are merged and deduplicated with the values defined for a post, which means you can define common properties in .meta.yml
and then add specific properties or overrides for each post.
Adding pages
Besides posts, it's also possible to add static pages to your blog by listing the pages in the nav
section of mkdocs.yml
. All generated indexes are included after the last specified page. For example, to add a page on the authors of the blog, add the following to mkdocs.yml
:
Customization
Custom index pages
If you want to add custom content to automatically generated archive and category indexes, e.g. to add a category description prior to the list of posts, you can manually create the category page in the same location where the built-in blog plugin would create it:
-
The easiest way is to first add the category to the blog post, then take the URL generated by the built-in blog plugin and create the file at the corresponding location in the [
blog_dir
][this is configurable] folder.Note that the shown directory listing is based on the default configuration. If you specify different values for the following options, be sure to adjust the path accordingly:
- [
blog_dir
][this is configurable] categories_url_format
categories_slugify
- [
You can now add arbitrary content to the newly created file, or set specific front matter properties for this page, e.g. to change the page description:
All post excerpts belonging to the category are automatically appended.
Overriding templates
The built-in blog plugin is built on the same basis as Material for MkDocs, which means you can override all templates used for the blog by using theme extension as usual.
The following templates are added by the built-in blog plugin:
blog.html
– Template for blog, archive and category indexblog-post.html
– Template for blog post