I’ve spent a big part of the last year working on documentation for SendGrid. I’ve learned a lot of things. You can read about how we broke down the problem of documentation at a high level and why documentation is critical for success in Cheat Codes for Good Documentation.
Below you’ll find the path we took, from the early days through last November’s switch to the current system, based on Jekyll. Most of what I’ll recommend applies to documenting an abstraction layer, e.g. an API.
Scope of SendGrid’s Docs
Just for context of what SendGrid’s docs look like, here is the output of a linklint check.
6 default indexes
230 html files
1 image file
77 other files
113 http links
28 https links
1 mailto link
1155 named anchors
Note: there is only 1 image file because images that are small enough are converted to embedded URI data and stored in the css. This is accomplished using juicer.
History of SendGrid’s Docs
The Early Days: Wiki-style
June 2009 – April 2011
The initial documentation was basically the Minimum Viable Product for docs. A wiki required minimal effort on the platform and backend. It was easy to add and edit info, but hard to do complex layouts. A lack of constraints lead to inconsistency across similar pages.
April 2011 – November 2012
WordPress was a step in the right direction but ultimately the wrong tool for the job.
- Easy to edit content
- Easier to admin than wiki
- More customizable than wiki, but not easy
- Potential security issues (ops says “not on our network,” third parties iffy)
- Change control is hard
- Lots of dependencies
- Slow load times
- Fragile — easy to bring down production.
- Sucks at handling code
WordPress will drive you mad.
Content and coverage is not enough.
We had decent content and product coverage but our documentation lacked consistency, organization, and any sort of user experience guidelines.
We weren’t giving users enough tools to self-serve and succeed. Our platform was getting in the way of our goals rather than helping us.
What Does Sustainable Mean?
We knew we needed more sustainable documentation. By sustainable I mean:
- Change tracking
- Ease of deploy
- Maintainability of platform
- Smart constraints
- Smart defaults
- Ease of editing content
- Defined structure
Not surprisingly, these are a lot of the same things that make code sustainable.
- Version Control
- Continuous Deploy (not for 1.0, but eventually)
- Won’t make ops think twice about security
- More robust platform
Robust for us meant a better platform in terms of reliability, scalability, speed, and customization than our existing solution.
We were willing to make tradeoffs in order to get a more solid platform, such as requiring a development environment to contribute docs, and requiring knowledge of HTML or markdown.
Our best option started to sound a lot like a static site.
Docs Built on Jekyll
November 2012 – Present
“Jekyll is a simple, blog aware, static site generator.”
It is a static site generator takes a bunch of templates, augments them with data and output from plugins, and outputs a complete HTML site that requires only a web server.
What is a Static Site Generator?
Static site generators can be found in many languages. Jekyll is written in ruby, so custom plugins are written in ruby. The templating language for Jekyll is called liquid, created by Shopify. If you don’t write ruby, chances are you can find a solid static site generator written in your language of choice.
Keep in mind that a static site truly means static. You have no access to any GET or POST data and no access to querystrings. If it’s not available at compile time, you can’t use it.
Who Uses Jekyll
- 37 Signals
- Github Pages
- Twitter Bootstrap
GitHub pages use Jekyll, with some limitations. No custom plugins are allowed.
But you can actually host any static content on github pages, so if you generate the site locally you can use custom code.
What Does Jekyll Look Like?
Typical Jekyll Scaffolding
Layouts reference includes, and posts and pages reference layouts. In most cases you will probably have an assets folder as well for holding things like images and scripts.
What the heck is front-matter? I don’t really know and it seems like a terribly non-descriptive name for such an important component of the system.
In simple terms, the front-matter is a file-level configuration header. Any file that has it will be processed by jekyll. You can add arbitrary metadata to the header and use it in your pages and layouts.
Basic YAML Front-matter Example
title: Docs Home
title: Docs Home
Basic Layout Example
Basic Page Example
Custom Liquid Block Example
Challenges Implementing Jekyll
- Longer initial development time — 2.5 months for 1 developer
- Converting content from WordPress was basically an ETL project.
- Dependencies can be a challenge for new contributors
- Uses metadocs on configuration
- Provided screencast on how to contribute via github web UI
- Screencast on how to fork repo, make change, and submit pull request
…but it feels like we got it right.