Implementing GitBook to manage open source documentation

Last month, we proudly published a new version of Strapi and our brand new website. In this context, we entirely rewrote the documentation and decided to make its contribution as easy as possible. To do so, we had to choose a great workflow and decided to make Gitbook a key part of it. In this article we will explain how we did it.

Disclaimer: the arguments listed heres are ours and may vary for other projects.

What we needed

We didn't know what tool to choose, but we had clear needs for our documentation:

  • Compatible with the new website: At this point we already knew that the new website would be a Strapi v3 application rendering views. The ideal solution should not prevent us from doing that.
  • Contribution in the mono-repository: In its latest version, every Strapi core modules are developed and maintained in a single GitHub repository. Versioning the documentation in the same repository was an evidence to make sure that it is up-to-date before each pull request acceptation.
  • Markdown syntax: Maintaining a full HTML documentation can become very confusing: a single tag error can break the entire documentation or simply the design itself. On top of that, Markdown syntax makes contributions clearer and is natively interpreted by GitHub.
  • Low development time: We did not have weeks to spend on developing a new static documentation generator.
  • Customization: We didn't want to get stuck because of a lack of customizations possibilities.
  • v1 documentation: Both v1 and v3 documentation had to be still available in the same place.
  • Search: The documentation should be searchable to make information easy to find.
  • Internationalization: English is the default language but the documentation will be probably translated in the future.

Options

Well, at this point we knew what we wanted, so started comparing options.

Building something from scratch

As developers, we all have the reflex to create our own tools, but doing that requires a lot of development time:

Pros

  • Total control: Creating our own solution is probably the most secure way to be sure to have the ability to add any custom feature.

Cons

  • Times consuming: Building such a tool from scratch requires to develop generic features, which wastes time.
  • Risk to make something buggy: Existing solutions are supposed to be tested and validated by thousands of people. Perhaps, our own solution would have contained bugs.

Pandoc

Pros

  • Supported dialects: From Markdown to Microsoft Word docx, Pandoc support a wide list of dialects.

Cons

  • Design: The generated documentation is almost pure HTML and requires an important redesign to look cleaner.
  • No Search: No search module supported.

MkDocs

Pros

  • Plugins system: MkDocs has a nice plugins system.
  • Easy setup: The setup is impressively fast.

Cons

  • Written in Python: Here at Strapi, we are big fan of Node.js and JavaScript and we appreciate tools using these technologies. Adding a new language in our stack makes things more complex.
  • Pure Bootstrap theme: The theme is easily configurable but requires some design to get something more original than the Bootstrap theme.

Docsify

Pros

  • Nice design: The documentation has a nice and clean design.
  • Available plugins: A list of plugins is available.
  • GitHub Pages: Docsify can be easily integrated with GitHub Pages.

Cons

  • SEO-unfriendly: Docsify generates a Single Page Application (SPA), what offers a great User Experience (no page reloading) but force having a pre-render tool to be crawled properly by the search engines.

GitBook

Gitbook logo

GitBook project is probably one of the most famous solutions, so we took a serious look at it:

Pros

Cons

  • Broken links: Any broken link can produce an error in the documentation generation.

Thanks to its plugins system, flexibility and easy use, we went for GitBook.

Implementation

Once the decision was done, we started implementing GitBook.

Coding

GitHub project update

In the GitHub repository, we added a docs folder containing the following architecture:

/docs
└── 1.x.x
|   └── en // English documentation
|   |   └── admin.md // `Admin` doc
|   |   └── ... // Other files
|   |   └── README.md // Introduction page
|   |   └── SUMMARY.md // Summary (left menu)
|   └── LANGS.md // List of supported languages
|   └── book.json // GitBook configuration (plugins, etc.)
└─ 3.x.x
   └─ en // English documentation
   |   └── advanced // Section `advanced`
   |   |   └── customize-admin.md // `advanced` section docu
   |   |   └── ... // Other files
   |   └── ... // Other directories
   |   └── README.md // Introduction page
   |   └── SUMMARY.md // Summary (left menu)
   └── LANGS.md // List of supported languages
   └── book.json // GitBook configuration (plugins, etc.)

GitBook script

After that, we added gitbook as a dependency of the Strapi project and created a script (./api/documentation/services/Documentation.js) to manage the documentation generation.

Strapi Gitbook steps

Here is the list of actions executed by this script:

  1. Clean the destination directories:
    • .docs: Temporary folder containing the docs files downloaded from GitHub.
    • public/documentation: Folder containing the generated documentation (HTML files) to serve them as public assets.
    • public/gitbook: Folder containing the GitBook theme and plugins.
  2. Download documentation files: Docs files are recursively downloaded from GitHub (using the GitHub API) and stored in .docs.
  3. Install GitBook plugins: For each version of the documentation, the command .node_modules/.bin/gitbook/ install /.docs/${version} is executed.
  4. Build: Then, it builds the documentation (.node_modules/.bin/gitbook/ build .docs/${version}).
  5. Copy generated documentation: The freshly created files (HTML, etc.) are copied from:
    • .docs/${version}/en to public/documentation/${version}.
    • .docs/${latestVersion}/en to public/documentation/ to make it available as the default documentation (accessible through https://strapi.io/documentation).
    • .docs/${latestVersion}/gitbook to public/documentation/gitbook in order to make GitBook assets available on every documentation's version.

CRON automation

To automatically reflect the GitHub documentation updates on the website, we created a CRON task which starts every 24 hours the script described in the previous paragraph.

Plugins used

To fill our needs we selected the following list of plugins:

  • edit-link
  • anchorjs
  • search
  • versions
  • ga
  • github
  • feathers-collapsible-menu
  • block-align

Customization

Default theme was looking fine, but we wanted to adjust the left menu's styles. So we added a file named website.css in the GitHub repository according to the GitBook documentation and the update was immediately effective.

Architecture

The website pages is served by a Strapi v3 application. This server is installed on a simple AWS EC2 micro instance. The Node.js server process is managed by pm2 and served behind a nginx reverse proxy.

For a better cache and assets delivery, the website (so the GitBook documentation files) are served by a AWS CloudFront (CDN) distribution.

Strapi website architecture

SEO migration

Some URLs of our previous documentation disappeared in the new version. To list them, we actively used the Google Search Console and adjusted our nginx configuration accordingly:

server {  
  listen 80;

  server_name strapi.io;

  rewrite ^/documentation/upload$ /documentation permanent;
  rewrite ^/documentation/cli$ /documentation/cli/CLI.html permanent;
  rewrite ^/documentation/email$ /documentation permanent;
  # ...

  location / {
    proxy_pass http://localhost:1337;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}

Integration in Travis test

Broken links can break documentation generation. Since the documentation is automatically rebuilt every day, it was important for us to make sure that the documentation's generation cannot break on the website server.

For this reason, we decided to add a script in the .travis.yml file. If any error occur during documentation generation, Travis notifies GitHub so we can fix it quickly.

Conclusion

The documentation generator is a central part of any open-source project. Choosing the right tool must be based on a specific needs list. At Strapi, we decided to choose GitBook for many reasons (plugins ecosystem, customisation, etc.) and are happy with it: https://strapi.io/documentation.

In the next few months we are going to use the Multi-Langual feature deeper to internationalize the documentation. In this way, feel free to contact us if you want to translate some content in your language.

And you, what tool did you choose to generate documentation?