Skip to content

Latest commit

 

History

History
571 lines (439 loc) · 14 KB

blog.mdx

File metadata and controls

571 lines (439 loc) · 14 KB
id title
blog
Blog

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

The blog feature enables you to deploy in no time a full-featured blog.

:::info

Check the Blog Plugin API Reference documentation for an exhaustive list of options.

:::

Initial setup {#initial-setup}

To setup your site's blog, start by creating a blog directory.

Then, add an item link to your blog within docusaurus.config.js:

module.exports = {
  themeConfig: {
    // ...
    navbar: {
      items: [
        // ...
        // highlight-next-line
        {to: 'blog', label: 'Blog', position: 'left'}, // or position: 'right'
      ],
    },
  },
};

Adding posts {#adding-posts}

To publish in the blog, create a Markdown file within the blog directory.

For example, create a file at website/blog/2019-09-05-hello-docusaurus-v2.md:

---
title: Welcome Docusaurus v2
description: This is my first post on Docusaurus 2.
slug: welcome-docusaurus-v2
authors:
  - name: Joel Marcey
    title: Co-creator of Docusaurus 1
    url: https://github.com/JoelMarcey
    image_url: https://github.com/JoelMarcey.png
  - name: Sébastien Lorber
    title: Docusaurus maintainer
    url: https://sebastienlorber.com
    image_url: https://github.com/slorber.png
tags: [hello, docusaurus-v2]
image: https://i.imgur.com/mErPwqL.png
hide_table_of_contents: false
---
Welcome to this blog. This blog is created with [**Docusaurus 2**](https://docusaurus.io/).

<!--truncate-->

This is my first post on Docusaurus 2.

A whole bunch of exploration to follow.

:::note

Docusaurus will extract a YYYY-MM-DD date from a file/folder name such as YYYY-MM-DD-my-blog-post-title.md.

This naming convention is optional, and you can provide the date as FrontMatter.

Example supported patterns
  • 2021-05-28-my-blog-post-title.md
  • 2021-05-28-my-blog-post-title.mdx
  • 2021-05-28-my-blog-post-title/index.md
  • 2021-05-28/my-blog-post-title.md
  • 2021/05/28/my-blog-post-title.md
  • 2021/05-28-my-blog-post-title.md
  • 2021/05/28/my-blog-post-title/index.md
  • ...

:::

:::tip

Using a folder can be convenient to co-locate blog post images alongside the Markdown file.

:::

The only required field in the front matter is title; however, we provide options to add more metadata to your blog post, for example, author information. For all possible fields, see the API documentation.

Blog list {#blog-list}

The blog's index page (by default, it is at /blog) is the blog list page, where all blog posts are collectively displayed.

Use the <!--truncate--> marker in your blog post to represent what will be shown as the summary when viewing all published blog posts. Anything above <!--truncate--> will be part of the summary. For example:

---
title: Truncation Example
---
All these will be part of the blog post summary.

Even this.

<!--truncate-->

But anything from here on down will not be.

Not this.

Or this.

By default, 10 posts are shown on each blog list page, but you can control pagination with the postsPerPage option in the plugin configuration. If you set postsPerPage: 'ALL', pagination will be disabled and all posts will be displayed on the first page. You can also add meta description to the blog list page for better SEO:

module.exports = {
  // ...
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        blog: {
          // highlight-start
          blogTitle: 'Docusaurus blog!',
          blogDescription: 'A Docusaurus powered blog!',
          postsPerPage: 'ALL',
          // highlight-end
        },
      },
    ],
  ],
};

Blog sidebar {#blog-sidebar}

The blog sidebar displays recent blog posts. The default number of items shown is 5, but you can customize with the blogSidebarCount option in the plugin configuration. By setting blogSidebarCount: 0, the sidebar will be completely disabled, with the container removed as well. This will increase the width of the main container. Specially, if you have set blogSidebarCount: 'ALL', all posts will be displayed.

You can also alter the sidebar heading text with the blogSidebarTitle option. For example, if you have set blogSidebarCount: 'ALL', instead of the default "Recent posts", you may would rather make it say "All posts":

module.exports = {
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        blog: {
          // highlight-start
          blogSidebarTitle: 'All posts',
          blogSidebarCount: 'ALL',
          // highlight-end
        },
      },
    ],
  ],
};

Blog post authors {#blog-post-authors}

Use the authors FrontMatter field to declare blog post authors.

Inline authors {#inline-authors}

Blog post authors can be declared directly inside the FrontMatter:

<Tabs groupId="author-frontmatter">
  <TabItem value="single" label="Single author">

```yml title="my-blog-post.md"
---
authors:
  name: Joel Marcey
  title: Co-creator of Docusaurus 1
  url: https://github.com/JoelMarcey
  image_url: https://github.com/JoelMarcey.png
---
```

  </TabItem>
  <TabItem value="multiple" label="Multiple authors">

```yml title="my-blog-post.md"
---
authors:
  - name: Joel Marcey
    title: Co-creator of Docusaurus 1
    url: https://github.com/JoelMarcey
    image_url: https://github.com/JoelMarcey.png
  - name: Sébastien Lorber
    title: Docusaurus maintainer
    url: https://sebastienlorber.com
    image_url: https://github.com/slorber.png
---
```

  </TabItem>
</Tabs>

:::tip

This option works best to get started, or for casual, irregular authors.

:::

:::info

Prefer usage of the authors FrontMatter, but the legacy author_* FrontMatter remains supported:

---
author: Joel Marcey
author_title: Co-creator of Docusaurus 1
author_url: https://github.com/JoelMarcey
author_image_url: https://github.com/JoelMarcey.png
---

:::

Global authors {#global-authors}

For regular blog post authors, it can be tedious to maintain authors information inlined in each blog post.

It is possible declare those authors globally in a configuration file:

jmarcey:
  name: Joel Marcey
  title: Co-creator of Docusaurus 1
  url: https://github.com/JoelMarcey
  image_url: https://github.com/JoelMarcey.png

slorber:
  name: Sébastien Lorber
  title: Docusaurus maintainer
  url: https://sebastienlorber.com
  image_url: https://github.com/slorber.png

:::tip

Use the authorsMapPath plugin option to configure the path. JSON is also supported.

:::

In blog posts FrontMatter, you can reference the authors declared in the global configuration file:

<Tabs groupId="author-frontmatter">
  <TabItem value="single" label="Single author">

```yml title="my-blog-post.md"
---
authors: jmarcey
---
```

  </TabItem>
  <TabItem value="multiple" label="Multiple authors">

```yml title="my-blog-post.md"
---
authors: [jmarcey, slorber]
---
```

  </TabItem>
</Tabs>

:::info

The authors system is very flexible and can suit more advanced use-case:

Mix inline authors and global authors

You can use global authors most of the time, and still use inline authors:

---
authors:
  - jmarcey
  - slorber
  - name: Inline Author name
    title: Inline Author Title
    url: https://github.com/inlineAuthor
    image_url: https://github.com/inlineAuthor
---
Local override of global authors

You can customize the global author's data on per-blog-post basis:

---
authors:
  - key: jmarcey
    title: Joel Marcey's new title
  - key: slorber
    name: Sébastien Lorber's new name
---
Localize the author's configuration file

The configuration file can be localized, just create a localized copy of it at:

website/i18n/<locale>/docusaurus-plugin-content-blog/authors.yml

:::

Reading time {#reading-time}

Docusaurus generates a reading time estimation for each blog post based on word count. We provide an option to customize this.

module.exports = {
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        blog: {
          // highlight-start
          showReadingTime: true, // When set to false, the "x min read" won't be shown
          readingTime: ({content, frontMatter, defaultReadingTime}) =>
            defaultReadingTime({content, options: {wordsPerMinute: 300}}),
          // highlight-end
        },
      },
    ],
  ],
};

The readingTime callback receives three parameters: the blog content text as a string, front matter as a record of string keys and their values, and the default reading time function. It returns a number (reading time in minutes) or undefined (disable reading time for this page).

The default reading time is able to accept additional options: wordsPerMinute as a number (default: 300), and wordBound as a function from string to boolean. If the string passed to wordBound should be a word bound (spaces, tabs, and line breaks by default), the function should return true.

:::tip

Use the callback for all your customization needs:

<Tabs>
<TabItem value="disable-per-post" label="Per-post disabling">

**Disable reading time on one page:**

```js title="docusaurus.config.js"
module.exports = {
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        blog: {
          showReadingTime: true,
          // highlight-start
          readingTime: ({content, frontMatter, defaultReadingTime}) =>
            frontMatter.hide_reading_time ? undefined : defaultReadingTime({content}),
          // highlight-end
        },
      },
    ],
  ],
};
```

Usage:

```yml "my-blog-post.md"
---
hide_reading_time: true
---

This page will no longer display the reading time stats!
```

</TabItem>
<TabItem value="passing-options" label="Passing options">

**Pass options to the default reading time function:**

```js title="docusaurus.config.js"
module.exports = {
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        blog: {
          // highlight-start
          readingTime: ({content, defaultReadingTime}) =>
            defaultReadingTime({content, options: {wordsPerMinute: 100}}),
          // highlight-end
        },
      },
    ],
  ],
};
```

</TabItem>
<TabItem value="using-custom-algo" label="Using custom algorithms">

**Use a custom implementation of reading time:**

```js title="docusaurus.config.js"
const myReadingTime = require('./myReadingTime');

module.exports = {
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        blog: {
          // highlight-next-line
          readingTime: ({content}) => myReadingTime(content),
        },
      },
    ],
  ],
};
```

</TabItem>
</Tabs>

:::

Feed {#feed}

You can generate RSS/Atom feed by passing feedOptions. By default, RSS and Atom feeds are generated. To disable feed generation, set feedOptions.type to null.

type BlogOptions = {
  feedOptions?: {
    type?: 'rss' | 'atom' | 'all' | null;
    title?: string;
    description?: string;
    copyright: string;
    language?: string; // possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
  };
};

Example usage:

module.exports = {
  // ...
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        blog: {
          feedOptions: {
            type: 'all',
            copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`,
          },
        },
      },
    ],
  ],
};

Accessing the feed:

The feed for RSS can be found at:

https://{your-domain}/blog/rss.xml

and for Atom:

https://{your-domain}/blog/atom.xml

Advanced topics {#advanced-topics}

Blog-only mode {#blog-only-mode}

You can run your Docusaurus 2 site without a landing page and instead have your blog's post list page as the index page. Set the routeBasePath to be '/' to indicate it's the root path.

module.exports = {
  // ...
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        docs: false,
        blog: {
          path: './blog',
          routeBasePath: '/', // Set this value to '/'.
        },
      },
    ],
  ],
};

:::caution

Don't forget to delete the existing homepage at ./src/pages/index.js or else there will be two files mapping to the same route!

:::

Multiple blogs {#multiple-blogs}

By default, the classic theme assumes only one blog per website and hence includes only one instance of the blog plugin. If you would like to have multiple blogs on a single website, it's possible too! You can add another blog by specifying another blog plugin in the plugins option for docusaurus.config.js.

Set the routeBasePath to the URL route that you want your second blog to be accessed on. Note that the routeBasePath here has to be different from the first blog or else there could be a collision of paths! Also, set path to the path to the directory containing your second blog's entries.

As documented for multi-instance plugins, you need to assign a unique id to the plugins.

module.exports = {
  // ...
  plugins: [
    [
      '@docusaurus/plugin-content-blog',
      {
        /**
         * Required for any multi-instance plugin
         */
        id: 'second-blog',
        /**
         * URL route for the blog section of your site.
         * *DO NOT* include a trailing slash.
         */
        routeBasePath: 'my-second-blog',
        /**
         * Path to data on filesystem relative to site dir.
         */
        path: './my-second-blog',
      },
    ],
  ],
};

As an example, we host a second blog here.