Skip to content

Basic blogs

Blogs are a great way to engage with your audience. Software developers can use a blog to announce new features, demonstrate their usage and provide background information. You can demonstrate competence by commenting on the state of the art or document your own work as best practice. Posts on current topics can help draw in visitors for your main website and can keep your audience engaged. Of course, you can blog about any topics close to your heart.

The blog plugin makes running a blog alongside your other content easy but you can also configure it to run a stand-alone blog if posts are the only kind of content you need.

After a brief overview of the basic concepts of a blog, this tutorial guides you through the process of configuring the blog plugin, setting up your blog, creating posts, and defining post metadata.

Time required: typically 20 minutes

Key concepts

Post, excerpt: a blog consists of a number of self-contained posts (often called articles) and an index page that shows the posts in reverse chronological order, with the most recent post at the top. The index page usually shows only a short excerpt and a link that the user can click to navigate to the full post.

Metadata: both the index page and the post itself list information such as when you published the post, when you updated it, who the author is, and what the expected reading time is.

Slug: since the blog posts are primarily arranged by time and not into a hierarchy, their URLs do not reflect such a structure. Instead, each post's URL contains a shortened description, the slug, which is usually derived from the first heading in the post.

Navigation: the main navigation structure is the timeline, which you can subdivide into categories. The main index page shows the more recent posts while an archive section allows access to older ones, organized by year. In addition, posts can be tagged and tag index pages provide an additional navigation structure based on content.

You can see all these elements on the Material for MkDocs blog.

Setting up your blog

The blog plugin is part of Material for MkDocs but you need to configure it in the mkdocs.yml.

Set up a blog

If you have not done so already, create a project for your blog, then edit the mkdocs.yml file to make sure if has the following content:

site_name: Blog Tutorial
site_description: an example blog set up following the tutorial
site_url: http://www.example.com

theme:
  name: material

plugins:
  - search
  - blog

The blog plugin will create a directory structure for your blog posts if it does not exist, so simply run mkdocs serve to get:

docs
├── blog
│   ├── index.md
│   └── posts
└── index.md

Now create your first blog post in docs/blog/posts. You can use any naming convention and directory structure you like for your posts, as long as they are inside docs/blog/posts.

Each post must have a page header, which appears at the top of the Markdown code between lines with three dashes. Within this header, you need to have at least a date entry but you can add other data, as you will see below. Following the header comes the page content. Note that it is important to have a level one heading as the plugin uses it to produce the slug. Also, by adding <!-- more --> to the page, you can define where the excerpt will end that the index page shows.

Write your first post

Create a file docs/blog/posts/myfirst.md with the following contents:

---
date:
  created: 2023-12-31
---

# Happy new years eve!

We hope you are all having fun and wish you all the best for the new year!
<!-- more -->

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.

Then, run mkdocs serve and point your web browser at http://localhost:8000/blog.

The blog plugin automatically creates navigation elements for the blog. The index page shows only the extract. When you select the "Continue reading" link, you will get to the full blog post. Note how it has a URL generated from the first-level heading.

Navigation

We also have a tutorial on navigation that shows you how to change the automatically created navigation and integrate the blog into your existing navigation structure. It shows how to create secondary nagigation, produce author pages, and control pagination.

Post metadata

In addition to the date, you can provide other metadata and give the plugin instructions, such as to treat a post as a draft or to pin it.

Drafts

You may want to produce a draft of a blog post and work with it locally but exclude it from the build that you publish. Simply add a field to the page header to indicate that a post is still in draft form.

Create a draft

Create a second blog post in docs/blogs/posts/draft.md with the following contents:

---
date:
  created: 2024-01-01
draft: true
---

# Happy new year!

Happy 2024 to everyone. Wishing you all the best!
<!-- more -->

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.

Now, note how the draft appears on the index page but with a label that indicates that it is a draft. When you run mkdocs build, the draft will not appear in the output:

$ mkdocs build
$ ls site/blog
site/blog
├── 2023
│   └── 12
│       └── 31
│           └── happy-new-years-eve
│               └── index.html
...

The first blog post for 2024 is not there yet because it is still in draft stage. Remember to remove the draft setting in the header when it is time to publish it.

If you are using the Insiders Edition, you can also create a folder to keep your drafts in and use the Meta plugin to add the draft header setting to all the posts in that folder. This has the advantage that it is easier to see which posts are still in draft form. We will cover the Meta plugin later on.

Edits

Sometimes, bloggers need to update a post. This might happen when you make a mistake or when something changes that you need to reflect in the post. To indicate you have edited a post, you can include an updated date in the page header.

Editing a post

Make a change to your first blog post, then add an edit date to the header:

---
date:
  created: 2023-12-31
  updated: 2024-01-02
---

The Metadata section of the blog post itself will contain the edit date, though the index page omits this detail by default.

Reading time

To give the reader some idea of how long it might take them to read a post, a read time is automatically calculated. If you want to override this, you can do so in the page header by specifying the number of minutes you estimate your readers will take the read the post.

Overriding the reading time

Add a reading time override to your first blog post:

---
date:
  created: 2023-12-31
  updated: 2024-01-02
readtime: 15
---

Pinning

Sometimes, blog authors want to 'pin' a specific post so that it will always appear at the top of the index page, no matter what else gets published. If you are using the Insiders Edition, you can achieve this by adding the pin attribute in the page header:

Pin a post

Add the pin attribute to your first blog post:

---
date:
  created: 2023-12-31
  updated: 2024-01-02
readtime: 15
pin: true
---

Observe how this makes the post appear on top of the index page even though its publication date is prior to other posts. A small pin icon shows that the post has been pinned.

When your blog is part of a wider site such as technical documentation, you will want to provide links from blog posts into your other content. One way you can do this is to have a related links section. In the Insiders Edition, the blog plugin can create one for you if you provide link targets in your page header:

Add a related links section

Add the following to a blog post:

---
date:
  created: 2023-12-31
...
links:
  - index.md
  - blog/index.md
---

The related links appear underneath the Metadata section.

The nice thing here is that you do not need to provide a page title. The plugin will deduce the link text by applying the same logic that MkDocs uses for the main navigation. In fact, the syntax is the same as that of the nav section in the mkdocs.yml, so you can override the title if you want and even define subsections:

Override the page titles

Change the link section to override the page titles:

---
date:
  created: 2023-12-31
...
links:
  - Homepage: index.md
  - Blog index: blog/index.md
  - External links:
    - Material documentation: https://squidfunk.github.io/mkdocs-material
---

The plugin renders related links in the left sidebar on screens that are wide enough and at the bottom of the post on narrow screens. Change the size of your browser window to see this in action.

Meta plugin

The Meta plugin is available in the Insiders Edition. It helps simplify the management of metadata that is common to a group of files in the same subdirectory. Instead of having to repeat the same metadata in the page headers of a number of files, you can add a .meta.yml file in the directory and the Meta plugin will merge its contents into the headers of all the pages contained. Settings from the page header take precedence, so you can always override settings by adding them to a post's header.

For example, you may want to manage drafts by keeping them in a directory together so that they are not only flagged as drafts but also easier to find. (Otherwise, you would need to inspect the page headers or trace back from the output to the files to figure out which posts are drafts.)

Drafts using the Meta plugin

You first need to activate the plugin in your mkdocs.yaml:

plugins:
  - search
  - blog
  - meta

Now create the folder for the drafts:

$ mkdir docs/blog/posts/drafts

TODO

Now, within this folder, crate a file .meta.yml that contains:

draft: true

Add another blog post and store it in docs/blog/posts/drafts. When you look at it locally, you will see the label that identifies it as a draft, while in the version built for publication it does not appear. To move a post from draft status to published, simply move it outside drafts/.

What's next?

You should now have a working blog. However, as it accumulates content, you may want to make sure that people can find posts they are interested in, so you may want to add secondary navigation with tags and categories. You may have more than one author and want to attribute posts to them as well as generate author pages for them. We have a tutorial on navigation, pagination, and authors that covers these topics.

You may want to increase engagement with your blog by allowing people to subscribe to an RSS feed or by setting up a comment system. The engagement and dissemination tutorial walks you through setting these up.