Skip to main content
Version: 3.5.2

πŸ“¦ plugin-content-blog

Provides the Blog feature and is the default blog plugin for Docusaurus.

some features production only

The feed feature works by extracting the build output, and is only active in production.

Installation​

npm install --save @docusaurus/plugin-content-blog
tip

If you use the preset @docusaurus/preset-classic, you don't need to install this plugin as a dependency.

You can configure this plugin through the preset options.

Configuration​

Accepted fields:

NameTypeDefaultDescription
pathstring'blog'Path to the blog content directory on the file system, relative to site dir.
editUrlstring | EditUrlFnundefinedBase URL to edit your site. The final URL is computed by editUrl + relativePostPath. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links.
editLocalizedFilesbooleanfalseThe edit URL will target the localized file, instead of the original unlocalized file. Ignored when editUrl is a function.
blogTitlestring'Blog'Blog page title for better SEO.
blogDescriptionstring'Blog'Blog page meta description for better SEO.
blogSidebarCountnumber | 'ALL'5Number of blog post elements to show in the blog sidebar. 'ALL' to show all blog posts; 0 to disable.
blogSidebarTitlestring'Recent posts'Title of the blog sidebar.
routeBasePathstring'blog'URL route for the blog section of your site. DO NOT include a trailing slash. Use / to put the blog at root path.
tagsBasePathstring'tags'URL route for the tags section of your blog. Will be appended to routeBasePath.
pageBasePathstring'page'URL route for the pages section of your blog. Will be appended to routeBasePath.
archiveBasePathstring | null'archive'URL route for the archive section of your blog. Will be appended to routeBasePath. DO NOT include a trailing slash. Use null to disable generation of archive.
authorsBasePathstring'authors'URL route for the authors pages of your blog. Will be appended to path.
includestring[]['**/*.{md,mdx}']Array of glob patterns matching Markdown files to be built, relative to the content path.
excludestring[]See example configurationArray of glob patterns matching Markdown files to be excluded. Serves as refinement based on the include option.
postsPerPagenumber | 'ALL'10Number of posts to show per page in the listing page. Use 'ALL' to display all posts on one listing page.
blogListComponentstring'@theme/BlogListPage'Root component of the blog listing page.
blogPostComponentstring'@theme/BlogPostPage'Root component of each blog post page.
blogTagsListComponentstring'@theme/BlogTagsListPage'Root component of the tags list page.
blogTagsPostsComponentstring'@theme/BlogTagsPostsPage'Root component of the "posts containing tag" page.
blogArchiveComponentstring'@theme/BlogArchivePage'Root component of the blog archive page.
blogAuthorsPostsComponentstring'@theme/Blog/Pages/BlogAuthorsPostsPage'Root component of the blog author page.
blogAuthorsListComponentstring'@theme/Blog/Pages/BlogAuthorsListPage'Root component of the blog authors page index.
remarkPluginsany[][]Remark plugins passed to MDX.
rehypePluginsany[][]Rehype plugins passed to MDX.
rehypePluginsany[][]Recma plugins passed to MDX.
beforeDefaultRemarkPluginsany[][]Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins.
beforeDefaultRehypePluginsany[][]Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins.
truncateMarkerRegExp/<!--\s*truncate\s*-->/ | \{\/\*\s*truncate\s*\*\/\}/Truncate marker marking where the summary ends.
showReadingTimebooleantrueShow estimated reading time for the blog post.
readingTimeReadingTimeFnThe default reading timeA callback to customize the reading time number displayed.
authorsMapPathstring'authors.yml'Path to the authors map file, relative to the blog content directory.
feedOptionsSee below{type: ['rss', 'atom']}Blog feed.
feedOptions.typeFeedType | FeedType[] | 'all' | nullRequiredType of feed to be generated. Use null to disable generation.
feedOptions.createFeedItemsCreateFeedItemsFn | undefinedundefinedAn optional function which can be used to transform and / or filter the items in the feed.
feedOptions.limitnumber | null | false20Limits the feed to the specified number of posts, false or null for all entries. Defaults to 20.
feedOptions.titlestringsiteConfig.titleTitle of the feed.
feedOptions.descriptionstring`${siteConfig.title} Blog`Description of the feed.
feedOptions.copyrightstringundefinedCopyright message.
feedOptions.xsltboolean | FeedXSLTOptionsundefinedCopyright message.
feedOptions.languagestring (See documentation for possible values)undefinedLanguage metadata of the feed.
sortPosts'descending' | 'ascending' 'descending'Governs the direction of blog post sorting.
processBlogPostsProcessBlogPostsFnundefinedAn optional function which can be used to transform blog posts (filter, modify, delete, etc...).
showLastUpdateAuthorbooleanfalseWhether to display the author who last updated the blog post.
showLastUpdateTimebooleanfalseWhether to display the last date the blog post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub actions/checkout, usefetch-depth: 0.
tagsstring | false | null | undefinedtags.ymlPath to the YAML tags file listing pre-defined tags. Relative to the blog content directory.
onInlineTags'ignore' | 'log' | 'warn' | 'throw'warnThe plugin behavior when blog posts contain inline tags (not appearing in the list of pre-defined tags, usually tags.yml).
onUntruncatedBlogPosts'ignore' | 'log' | 'warn' | 'throw'warnThe plugin behavior when blog posts do not contain a truncate marker.

Types​

EditUrlFn​

type EditUrlFunction = (params: {
blogDirPath: string;
blogPath: string;
permalink: string;
locale: string;
}) => string | undefined;

ReadingTimeFn​

type ReadingTimeOptions = {
wordsPerMinute: number;
wordBound: (char: string) => boolean;
};

type ReadingTimeCalculator = (params: {
content: string;
frontMatter?: BlogPostFrontMatter & Record<string, unknown>;
options?: ReadingTimeOptions;
}) => number;

type ReadingTimeFn = (params: {
content: string;
frontMatter: BlogPostFrontMatter & Record<string, unknown>;
defaultReadingTime: ReadingTimeCalculator;
}) => number | undefined;

FeedType​

type FeedType = 'rss' | 'atom' | 'json';

FeedXSLTOptions​

Permits to style the blog XML feeds so that browsers render them nicely with XSLT.

  • Use true to let the blog use its built-in .xsl and .css files to style the blog feed
  • Use a falsy value (undefined | null | false) to disable the feature
  • Use a string to provide a file path to a custom .xsl file relative to the blog content folder. By convention, you must provide a .css file with the exact same name.
type FeedXSLTOptions =
| boolean
| undefined
| null
| {
rss?: string | boolean | null | undefined;
atom?: string | boolean | null | undefined;
};

CreateFeedItemsFn​

type CreateFeedItemsFn = (params: {
blogPosts: BlogPost[];
siteConfig: DocusaurusConfig;
outDir: string;
defaultCreateFeedItemsFn: CreateFeedItemsFn;
}) => Promise<BlogFeedItem[]>;

ProcessBlogPostsFn​

type ProcessBlogPostsFn = (params: {
blogPosts: BlogPost[];
}) => Promise<void | BlogPost[]>;

Example configuration​

You can configure this plugin through preset options or plugin options.

tip

Most Docusaurus users configure this plugin through the preset options.

If you use a preset, configure this plugin through the preset options:

docusaurus.config.js
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
blog: {
path: 'blog',
// Simple use-case: string editUrl
// editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/',
// Advanced use-case: functional editUrl
editUrl: ({locale, blogDirPath, blogPath, permalink}) =>
`https://github.com/facebook/docusaurus/edit/main/website/${blogDirPath}/${blogPath}`,
editLocalizedFiles: false,
blogTitle: 'Blog title',
blogDescription: 'Blog',
blogSidebarCount: 5,
blogSidebarTitle: 'All our posts',
routeBasePath: 'blog',
include: ['**/*.{md,mdx}'],
exclude: [
'**/_*.{js,jsx,ts,tsx,md,mdx}',
'**/_*/**',
'**/*.test.{js,jsx,ts,tsx}',
'**/__tests__/**',
],
postsPerPage: 10,
blogListComponent: '@theme/BlogListPage',
blogPostComponent: '@theme/BlogPostPage',
blogTagsListComponent: '@theme/BlogTagsListPage',
blogTagsPostsComponent: '@theme/BlogTagsPostsPage',
remarkPlugins: [require('./my-remark-plugin')],
rehypePlugins: [],
beforeDefaultRemarkPlugins: [],
beforeDefaultRehypePlugins: [],
truncateMarker: /<!--\s*(truncate)\s*-->/,
showReadingTime: true,
feedOptions: {
type: '',
title: '',
description: '',
copyright: '',
language: undefined,
createFeedItems: async (params) => {
const {blogPosts, defaultCreateFeedItems, ...rest} = params;
return defaultCreateFeedItems({
// keep only the 10 most recent blog posts in the feed
blogPosts: blogPosts.filter((item, index) => index < 10),
...rest,
});
},
},
},
},
],
],
};

Markdown front matter​

Markdown documents can use the following Markdown front matter metadata fields, enclosed by a line --- on either side.

Accepted fields:

NameTypeDefaultDescription
authorsAuthorsundefinedList of blog post authors (or unique author). Read the authors guide for more explanations. Prefer authors over the author_* front matter fields, even for single author blog posts.
authorstringundefined⚠️ Prefer using authors. The blog post author's name.
author_urlstringundefined⚠️ Prefer using authors. The URL that the author's name will be linked to. This could be a GitHub, X, Facebook profile URL, etc.
author_image_urlstringundefined⚠️ Prefer using authors. The URL to the author's thumbnail image.
author_titlestringundefined⚠️ Prefer using authors. A description of the author.
titlestringMarkdown titleThe blog post title.
datestringFile name or file creation timeThe blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, 2021-04-15-blog-post.mdx, 2021-04-15-blog-post/index.mdx, 2021/04/15/blog-post.mdx. Otherwise, it is the Markdown file creation time.
tagsTag[]undefinedA list of strings or objects of two string fields label and permalink to tag to your post. Strings can be a reference to keys of a tags file (usually tags.yml)
draftbooleanfalseDraft blog posts will only be available during development.
unlistedbooleanfalseUnlisted blog posts will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link.
hide_table_of_contentsbooleanfalseWhether to hide the table of contents to the right.
toc_min_heading_levelnumber2The minimum heading level shown in the table of contents. Must be between 2 and 6 and lower or equal to the max value.
toc_max_heading_levelnumber3The max heading level shown in the table of contents. Must be between 2 and 6.
keywordsstring[]undefinedKeywords meta tag, which will become the <meta name="keywords" content="keyword1,keyword2,..."/> in <head>, used by search engines.
descriptionstringThe first line of Markdown contentThe description of your document, which will become the <meta name="description" content="..."/> and <meta property="og:description" content="..."/> in <head>, used by search engines.
imagestringundefinedCover or thumbnail image that will be used as the <meta property="og:image" content="..."/> in the <head>, enhancing link previews on social media and messaging platforms.
slugstringFile pathAllows to customize the blog post URL (/<routeBasePath>/<slug>). Support multiple patterns: slug: my-blog-post, slug: /my/path/to/blog/post, slug: /.
last_updateFrontMatterLastUpdateundefinedAllows overriding the last update author/date. Date can be any parsable date string.
type FrontMatterLastUpdate = {date?: string; author?: string};

type Tag = string | {label: string; permalink: string};

// An author key references an author from the global plugin authors.yml file
type AuthorKey = string;

// Social platform name -> Social platform link
// Example: {MyPlatform: 'https://myplatform.com/myusername'}
// Pre-defined platforms ("x", "github", "twitter", "linkedin", "stackoverflow") accept handles:
// Example: {github: 'slorber'}
type AuthorSocials = Record<string, string>;

type Author = {
key?: AuthorKey;
name: string;
title?: string;
url?: string;
image_url?: string;
socials?: AuthorSocials;
};

// The front matter authors field allows various possible shapes
type Authors = AuthorKey | Author | (AuthorKey | Author)[];

Example:

---
title: Welcome Docusaurus
authors:
- slorber
- yangshun
- name: Joel Marcey
title: Co-creator of Docusaurus 1
url: https://github.com/JoelMarcey
image_url: https://github.com/JoelMarcey.png
socials:
x: joelmarcey
github: JoelMarcey
tags: [docusaurus]
description: This is my first post on Docusaurus.
image: https://i.imgur.com/mErPwqL.png
hide_table_of_contents: false
---

A Markdown blog post

Tags File​

Use the tags plugin option to configure the path of a YAML tags file.

By convention, the plugin will look for a tags.yml file at the root of your content folder(s).

This file can contain a list of predefined tags. You can reference these tags by their keys in Markdown files thanks to the tags front matter.

Keeping tags consistent

Using a tags file, you can ensure that your tags usage is consistent across your plugin content set. Use the onInlineTags: 'throw' plugin option to enforce this consistency and prevent usage of inline tags declared on the fly.

Types​

The YAML content of the provided tags file should respect the following shape:

type Tag = {
label?: string; // Tag display label
permalink?: string; // Tag URL pathname segment
description?: string; // Tag description displayed in the tag page
};

type TagsFileInput = Record<string, Partial<Tag> | null>;

Example​

tags.yml
releases:
label: 'Product releases'
permalink: '/product-releases'
description: 'Content related to product releases.'

# A partial tag definition is also valid
announcements:
label: 'Announcements'

# An empty tag definition is also valid
# Other attributes will be inferred from the key
emptyTag:
content.md
---
tags: [releases, announcements, emptyTag]
---

# Title

Content

Authors File​

Use the authors plugin option to configure the path of a YAML authors file.

By convention, the plugin will look for a authors.yml file at the root of your blog content folder(s).

This file can contain a list of predefined global blog authors. You can reference these authors by their keys in Markdown files thanks to the authors front matter.

Types​

The YAML content of the provided authors file should respect the following shape:

type AuthorsMapInput = {
[authorKey: string]: AuthorInput;
};

type AuthorInput = {
name?: string;
title?: string;
description?: string;
imageURL?: string;
url?: string;
email?: string;
page?: boolean | {permalink: string};
socials?: Record<string, string>;
[customAuthorAttribute: string]: unknown;
};

Example​

tags.yml
slorber:
name: SΓ©bastien Lorber
title: Docusaurus maintainer
url: https://sebastienlorber.com
image_url: https://github.com/slorber.png
page: true
socials:
x: sebastienlorber
github: slorber

jmarcey:
name: Joel Marcey
title: Co-creator of Docusaurus 1
url: https://github.com/JoelMarcey
image_url: https://github.com/JoelMarcey.png
email: [email protected]
page:
permalink: '/joel-marcey'
socials:
x: joelmarcey
github: JoelMarcey
blog/my-blog-post.md
---
authors: [slorber, jmarcey]
---

# My Blog Post

Content

i18n​

Read the i18n introduction first.

Translation files location​

  • Base path: website/i18n/[locale]/docusaurus-plugin-content-blog
  • Multi-instance path: website/i18n/[locale]/docusaurus-plugin-content-blog-[pluginId]
  • JSON files: extracted with docusaurus write-translations
  • Markdown files: website/i18n/[locale]/docusaurus-plugin-content-blog

Example file-system structure​

website/i18n/[locale]/docusaurus-plugin-content-blog
β”‚
β”‚ # translations for website/blog
β”œβ”€β”€ authors.yml
β”œβ”€β”€ first-blog-post.md
β”œβ”€β”€ second-blog-post.md
β”‚
β”‚ # translations for the plugin options that will be rendered
└── options.json