How to Create and Manage Blog Posts in Docusaurus: The Complete Guide
Docusaurus provides a first-class blogging engine through the @docusaurus/plugin-content-blog package that automatically generates paginated list pages, tag archives, author profiles, RSS feeds, and SEO structured data from Markdown files placed in the blog/ directory.
The facebook/docusaurus repository treats blogging as a core content type, with the plugin scanning your blog/ folder, validating front-matter schemas, and constructing static routes for each post. By mastering how to create and manage blog posts in Docusaurus, you gain access to automated reading-time calculations, draft/unlisted post controls, and centralized author management through declarative YAML files.
Configuring the Blog Plugin
The blog functionality is typically enabled via the classic preset in your docusaurus.config.js. The configuration object mirrors the PluginOptions type defined in packages/docusaurus-plugin-content-blog/src/types.ts.
// docusaurus.config.js
module.exports = {
presets: [
[
'classic',
{
blog: {
showReadingTime: true,
feedOptions: {
type: ['rss', 'atom'],
xslt: true,
},
onInlineTags: 'warn',
onInlineAuthors: 'warn',
onUntruncatedBlogPosts: 'warn',
editUrl: 'https://github.com/you/your-repo/edit/main/blog/',
},
},
],
],
};
Key configuration options include showReadingTime to display estimated reading duration on list pages, feedOptions to generate RSS/Atom feeds via src/feed.ts, and warning flags to enforce best practices for tags, authors, and content truncation.
Creating a Blog Post
File Location and Naming
Place your content files inside the blog/ directory at your site root. The plugin locates these files using the path defined in your configuration (defaulting to blog). You can embed the publication date directly in the filename—such as 2023-09-29-my-post.md—or specify it exclusively in front-matter. The parseBlogFileName utility in packages/docusaurus-plugin-content-blog/src/blogUtils.ts extracts the slug and date from the filename automatically.
Front Matter Schema
Every post must include metadata following the BlogPostFrontMatter schema, validated in src/frontMatter.ts. Required fields include title, while optional fields control routing, visibility, and social sharing.
---
title: "Deploying with Docusaurus"
date: 2023-09-29
tags: [deployment, ci-cd]
authors: [alice, bob]
slug: /deploy-guide
image: ./img/deploy.png
description: "A step-by-step guide to deploying Docusaurus sites."
draft: false
unlisted: false
---
Your content here...
The draft and unlisted boolean flags are processed by the isDraft and isUnlisted helpers in blogUtils.ts. A draft post is excluded from production builds entirely, while an unlisted post remains accessible by direct URL but is omitted from paginated list pages and tag archives.
Content Truncation
To display excerpts on the blog list page, insert a truncation marker after the opening paragraph. Use <!-- truncate --> for standard Markdown or {/* truncate */} for MDX files. The plugin validates the presence of this marker according to your onUntruncatedBlogPosts configuration setting in blogUtils.ts.
---
title: "My Post"
---
This introduction appears on the list page.
<!-- truncate -->
This content only appears on the full post page.
Managing Tags and Authors
Centralized Tag Definitions
Instead of defining tags inline, create a tags.yml file in your blog directory to centralize metadata. The plugin reads this file via getTagVisibility and groups posts using getBlogTags in blogUtils.ts.
# blog/tags.yml
tutorial:
label: Tutorial
description: Step-by-step Docusaurus guides
permalink: /tags/tutorial
news:
label: News
description: Product updates and announcements
When a post references tags: [tutorial], Docusaurus automatically generates a paginated tag page at /tags/tutorial using the metadata defined in this YAML file.
Author Management with YAML
Similarly, define reusable authors in an authors.yml file. The getBlogPostAuthors helper in src/authors.ts resolves front-matter references to these definitions, merging any inline overrides.
# blog/authors.yml
alice:
name: Alice Chen
title: Lead Maintainer
url: https://github.com/alice
image_url: ./img/alice.png
bob:
name: Bob Smith
title: Technical Writer
url: https://github.com/bob
Reference these keys in your post front-matter: authors: [alice]. You can also override specific fields inline for one-off customizations without modifying the global author definition.
Advanced Features and SEO Optimization
Reading Time and Structured Data
The readingTime utility in src/readingTime.ts calculates estimated reading duration based on word count. When showReadingTime: true is enabled, this estimate renders on list pages alongside each post title.
For search engine optimization, structuredDataUtils.ts generates JSON-LD structured data incorporating your image, description, and keywords front-matter fields. This ensures posts appear as rich results in search engines with proper Open Graph tags and schema markup.
RSS and Atom Feeds
The feed generation system in src/feed.ts automatically produces rss.xml and atom.xml files based on your feedOptions configuration. These feeds include full post content or excerpts depending on your privacy settings, and support XSLT styling for human-readable feed rendering in browsers.
Summary
- Enable the blog plugin via the classic preset in
docusaurus.config.js, configuring reading time, feeds, and validation warnings. - Create posts as Markdown or MDX files in the
blog/directory, using either filename dates or front-matter dates for publication scheduling. - Validate front-matter using the
BlogPostFrontMatterschema, utilizingdraftto hide posts from production andunlistedto exclude them from listings while keeping them accessible. - Organize metadata centrally using
authors.ymlfor contributor profiles andtags.ymlfor topic categorization, referenced by key in post front-matter. - Truncate content with
<!-- truncate -->markers to control excerpt generation on paginated list pages. - Optimize for discovery with automatic reading-time calculations, SEO structured data, and syndication feeds generated by the plugin internals.
Frequently Asked Questions
How do I hide a blog post from the production site?
Set draft: true in the post front-matter. According to the isDraft helper in packages/docusaurus-plugin-content-blog/src/blogUtils.ts, draft posts are filtered out during the build process and will not appear in production deployments, though they remain visible in development mode.
Can I use a custom URL slug different from the filename?
Yes. Add a slug field to your front-matter, such as slug: /my-custom-path. The plugin respects this override when generating routes, allowing you to maintain semantic filenames like 2024-01-01-post.md while serving the content at /blog/my-custom-path.
How does Docusaurus calculate reading time for blog posts?
The plugin imports the readingTime utility from src/readingTime.ts, which analyzes the word count of your Markdown content and applies a standard words-per-minute calculation. Enable showReadingTime: true in your blog configuration to display this estimate on list pages.
What is the difference between tags defined in front-matter and the tags.yml file?
Inline tags in front-matter (tags: [tutorial]) reference keys defined in tags.yml. The getBlogTags function in blogUtils.ts merges these references with the centralized definitions to generate tag pages with consistent labels, descriptions, and permalinks. Using tags.yml ensures uniform metadata across all posts sharing the same tag.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →