Towards Docusaurus 2
Docusaurus was officially announced over nine months ago as a way to easily build open source documentation websites. Since then, it has amassed over 8,600 GitHub Stars, and is used by many popular open source projects such as React Native, Babel, Jest, Reason and Prettier.
There is a saying that the very best software is constantly evolving, and the very worst is not. In case you are not aware, we have been planning and working on the next version of Docusaurus 🎉.
はじめに
It all started with this RFC issue opened by Yangshun towards the end of June 2018.
[RFC] Docusaurus v2 · Issue #789 · facebook/docusaurus
These are some of the problems I'm seeing in Docusaurus now and also how we can address them in v2. A number of the ideas here were inspired by VuePress and other static site generators. In the current static site generators ecosystem, t...
Most of the suggested improvements are mentioned in the issue; I will provide details on some of issues in Docusaurus 1 and how we are going to address them in Docusaurus 2.
Infrastructure
Content
A Docusaurus 1 website is, in fact, built into a bunch of static HTML pages. Despite using React, we were not fully utilizing the features React offered, such as component state, which allows for dynamic and interactive pages. React was only used as a templating engine for static content and interactivity has to be added through script tags and dangerouslySetInnerHTML
😱.
In addition, there is not an easy way to change how Docusaurus loads content. For example, adding CSS preprocessors such as Sass and Less was not supported natively and involved many user hacks of adding custom scripts.
For Docusaurus 2, we will be using webpack as a module bundler and we are changing the way we serve content. Adding CSS preprocessors will be as easy as adding a webpack loader. Instead of a pure static HTML, during build time we will create a server-rendered version of the app and render the corresponding HTML. A Docusaurus site will be essentially an isomorphic/universal application. This approach is heavily inspired by Gatsby.
バージョニング
If you have been using Docusaurus for a while, you might notice that Docusaurus creates versioned docs if and only if the docs content are different.
For example, if we have docs/hello.md
:
---
id: hello
title: hello
---
Hello world !
And we cut version 1.0.0, Docusaurus will create versioned_docs/version-1.0.0/hello.md
:
---
id: version-1.0.0-hello
title: hello
original_id: hello
---
Hello world !
However, if there are no changes to hello.md
when cutting v2.0.0, Docusaurus will not create any versioned docs for that document. In other words, versioned_docs/version-2.0.0/hello.md
will not exist.
This can be very confusing for users; if they want to edit the v2.0.0 docs, they have to edit versioned_docs/version-1.0.0/hello.md
or manually add versioned_docs/version-2.0.0/hello.md
. This could potentially lead to unwanted bugs. Here is a real scenario in Jest.
In addition, this adds complexity within the codebase as we require a mechanism for version fallbacks. And during build time, Docusaurus has to replace the linking to the correct version. This is also the cause of a bug where renaming docs breaks links in old versions.
For Docusaurus 2, every time we cut a new version, we will instead take a snapshot of all the docs. We will not require the content of a document to have changed. This is a space complexity trade-off for a better developer and user experience. We will use more space for better separation of concerns and guaranteed correctness.
Translation
Docusaurus allows for easy translation functionality by using Crowdin. Documentation files written in English are uploaded to Crowdin for translation by users within a community. We always assumed that English is the default language, but this might not be the case for all users. We have seen plenty of non-English open source projects using Docusaurus.
For Docusaurus 2, we will not assume English is the default language. When a user enables internationalization, they have to set a default language in siteConfig.js
. We will then assume that all the files in docs
are written in that language.
In addition, after working on the MVP of Docusaurus 2, I realized that it is possible not to use Crowdin for translations. Thus, we might need to add an additional workflow to enable that scenario. However, we will still strongly recommend people use Crowdin for easier integration.
Customizability
Layout
The current state of Docusaurus is that it is in charge of the entire layout and styling, unintentionally making it very hard for users to customize their site's appearance to their wishes.
For Docusaurus 2, layout and styling should be controlled by the user. Docusaurus will handle the content generation, routing, translation, and versioning. Inspired by create-react-app and VuePress, Docusaurus will still provide a default theme, which the user can eject from, for further layout and styling customization. This means that it is very possible for the user to even change the HTML meta by using React Helmet. Community-based themes are also very possible. This approach of allowing users to be in charge of layout and styling is taken by most static site generators.
Markdown
Our Markdown parsing is currently powered by Remarkable. What if the user wants to use Markdown-it or even MDX? And then there is an issue of which syntax highlighter to use, (e.g: Prism vs Highlight.js). We should leave these choices open to the user.
For Docusaurus 2, users can eject and choose their own Markdown parser. It does not matter if they want to use another Markdown parser such as Remark, or even their own in-house Markdown parser. As a rule of thumb, the user has to provide a React component, in which we will provide a children props containing the RAW string of Markdown. By default, we will use Remarkable for the Markdown parser and Highlight.js for the syntax highlighting. The default parser could still change in the future as we're still experimenting with different Markdown parsers.
検索
Our core search functionality is based on Algolia. There are requests by users to be able to use different search offerings, such as lunrjs
for offline search.
I personally like Algolia and we have a great experience working with them. They are very responsive; we can easily submit a pull request to Algolia since their DocSearch
is open source. For example, I recently submitted this PR that enables DocSearch to scrape alternate languages in sitemap.
For Docusaurus 2, we will allow users to customize the search box. Users simply need to eject from the default theme and modify the Search UI (a React component). However, we will still use Algolia in the default theme.