Skip to main content

Introducing Docusaurus

· 9 min read
Joel Marcey

We are very happy to introduce Docusaurus to help you manage one or many open source websites.

We created Docusaurus for the following reasons:

  1. To put the focus on writing good documentation instead of worrying about the infrastructure of a website.
  2. To provide features that many of our open source websites need like blog support, search and versioning.
  3. To make it easy to push updates, new features, and bug fixes to everyone all at once.
  4. And, finally, to provide a consistent look and feel across all of our open source projects.

Docusaurus is a tool designed to make it easy for teams to publish documentation websites without having to worry about the infrastructure and design details. At its core, all a user has to provide are documentation files written in Markdown, customization of a provided home page written in React, and a few configuration modifications. Docusaurus handles the rest by providing default styles, site formatting, and simple document navigation. Getting started is easy, as users can install it using npm or yarn via a simple initialization script that creates a working example website out of the box.

Docusaurus also provides core website and documentation features out-of-the-box including blog support, internationalization, search, and versioning. While some projects may not require any of these features, enabling them is generally a matter of updating configuration options instead of having to add the infrastructure from the ground up. As more features get added to Docusaurus, users just can easily update to the latest version. This can be done by simply running npm or yarn update and updating configuration options. Users or teams will no longer need to manually rework their entire website infrastructure each time a new feature gets added.

The Birth of docusaurus

When Facebook first started their open source program, many teams implemented a custom website for each of their open source projects. This approach presented challenges when the open source program team was asked to help the project teams improve their documentation. Since each site was unique, adding basic infrastructure such as a blog, consistent navigation, search, etc. became challenging undertakings.

The open source team tried to help mitigate this problem by coming up with a standard template, based on Jekyll, that could be used as a starting point for a project website. We asked our new projects to manually copy our template source to their repo, write their docs, and publish. This template approach was adopted by most of open source projects launched; some existing projects even converted their custom website implementations to the new template as well.

The problem with the "copy the template to your repo" approach is that, even though the platform is consistent, pushing updates becomes unmaintainable across an entire suite of projects already using the template. This is because we lost control of the template after a project copied it to their repo. Projects were free to modify the template as desired and apply their own project-specific features to it. So while projects share the same site generation platform, they have now diverted enough where they cannot take advantage of the new features we have added to the template over time. There was no easy way we could ask all current projects to "copy" a new version of the template since it might break their existing site or remove features that they have added on their own. Instead, we would have to apply the updates manually to each project one-by-one. This became very problematic when projects started asking for our team for internationalization support within the template, requiring low-level changes to how the template was structured and generated.

So we started thinking about what we could do to help mitigate the challenge of keeping sites updated and consistent across our entire portfolio. We also wanted multiple projects to share the same site generation software. We wanted them to start out with the same template, and yet have the flexibility to customize and adapt their site theme to suit their needs. They should be able to extend and customize their site, but when we update the underlying infrastructure with fixes and features, the project should be able update simply and without any breaking changes.

Docusaurus was born!

At Facebook, Docusaurus allows us to quickly get different projects up and running with documentation websites, especially for teams who don't have much experience with web development or primarily want a basic site to showcase their project. Docusaurus already supports sites needing more advanced features like internationalization for Jest and versioning for React Native. As different projects request new features for their sites, they are added to Docusaurus and simultaneously provided to all projects! All together, this ends up greatly reducing the work needed to maintain different sites for different projects. Our teams are able to focus on keeping their projects healthier by spending more time adding features, fixing bugs, and writing documentation.

Getting Up and Running

At its core, we wanted sites running Docusaurus to be simple to use. With one installation command and some simple configuration, you can actually have a default running website.

When you run docusaurus-init, you will see a structure similar to:

root-of-repo
├── docs-examples-from-docusaurus
│ ├── doc1.md
│ ├── doc2.md
│ ├── doc3.md
│ ├── example-doc4.md
│ └── example-doc5.md
├── website
│ ├── blog-examples-from-docusaurus
│ │ ├── 2016-03-11-blog-post.md
│ │ └── 2017-04-10-blog-post-two.md
│ ├── core
│ │ └── Footer.js
│ ├── node_modules
│ ├── package.json
│ ├── pages
│ ├── sidebars.json
│ ├── siteConfig.js
│ └── static

With the exception of node_modules and package.json, all the directories and files you see are where you customize and add content to your Docusaurus-based website. The docs folder is where you add your Markdown that represents your documentation; the blog folder is where you add your Markdown for your blog posts; siteConfig.js is where you make most of the customizations for your site; sidebars.json is where you maintain the layout and content of the sidebar for your documentation; the pages folder is where you add custom pages for your site; the static folder is where all of your static assets go (e.g., CSS stylesheets and images); and the core folder is where you can customize core components of the site, in this case the footer.

How does Docusaurus work?

Docusaurus is written primarily in JavaScript and React, replacing Jekyll which we used in the old template. We use Remarkable for our Markdown rendering and highlight.js for our code block syntax highlighting. The core of Docusaurus' functionality is in the lib directory of the Docusaurus repo. The general structure looks like:

root-of-Docusaurus
├── lib
│ ├── core
│ ├── server
│ │ ├── generate.js
│ │ ├── server.js
│ │ └── ...and more files
│ ├── static
│ ├── build-files.js
│ ├── copy-examples.js
│ ├── generate-feed.js
│ ├── publish-gh-pages.js
│ ├── rename-version.js
│ ├── start-server.js
│ ├── versions.js
│ └── write-translations.js

The key files here are build-files.js and start-server.js. There are many similarities between these two files: build-files.js is used to build the physical artifacts for serving by an external web server. start-server.js is used to run the Docusaurus server and locally test your site. Both go through the following general process to take all of the Markdown and configuration to create a runnable website:

  1. Process your website settings in siteConfig.js
  2. Read the document metadata that exists in all the Markdown files in your docs directory.
  3. Create a table of contents for your documents based upon the IDs extracted from the metadata.
  4. Convert the Markdown to HTML, including doing link replacement.
  5. These files will go in a build/docs directory of the compiled site, and any translated versions will go into a language specific folder within the build/docs folder.
  6. Repeat 1-3 for blog posts.
  7. The blog file will go in a build/blog directory of the compiled site.
  8. Read the main.css file and concatenate any user-defined css into master css file that will be in the build/css directory of the compiled site.
  9. Copy images into an build/img directory of the compiled site.
  10. Take any custom pages that were added to the pages folder of the site and compile/copy those into the root build directory of the compiled site. Any translated versions will go into a language specific folder within build.
  11. Create CNAME and sitemap.xml files and add those to build.

Note that this process does not take into full account how translations or versioning works. The underlying details of those features will be saved for future blog posts.

The final structure of your compiled site will look similar to:

build
├── website
│ ├── CNAME
│ ├── blog
│ ├── css
│ ├── docs
│ ├── en
│ ├── help.html # custom page
│ ├── img
│ ├── index.html # landing page
│ ├── sitemap.xml
│ └── users.html # custom page

Community

We welcome your contributions to Docusaurus, whether you want to use it for your own site, you want to contribute to the Docusaurus core or just have questions. Follow us on GitHub and Twitter.

Acknowledgements

Docusaurus wouldn't exist without the work of the rest of the core Docusaurus team: Eric Nakagawa, Hector Ramos, Eric Vicenti and Frank Li — a former intern at Facebook who implemented the core technology and features.

Special thanks also goes out to our earliest adopters of Docusaurus:

Without their dedication to creating or migrating their websites over to the platform, we would have not have been in the position where we are today.

Resources