In 2016, I migrated the API and front-end documentation of an e-commerce platform from Contentful to Slate as my first solo (and major) ruby project. At the time it was migrated, there were probably around 20 API endpoints documented and none of which had a swagger spec. Not only were there APIs, but there were TWO front-end frameworks that needed to be contained within the same site. My intent of this post is to discuss the specific problems this project posed, how they were tackled, and some constraints. If you are investigating static sites or Slate as a documentation solution, I hope you find value in my experiences.
As with any product, I had a wishlist of improvements. But it is easy for your eyes to be bigger than your stomach.
- Information architecture was atrocious. Users tended to bookmark pages more than suffer the structure.
- API resource pages were split and not linked to each other.
- No search, making the above problems even worse.
- Code samples existed only in SDKs and clients hosted on github.
- Basic getting started information was buried
- Load time was meh.
- Updating content required a user seat.
- No SAML/SSO which mattered for a company that managed off- and on-boarding through LDAP.
That list doesn't seem so bad, but with the curse of knowledge, I knew there was more to each than meets the eye. Having the luxury of experiencing Twilio's API documentation, it was tough knowing the high standard it would be compared to.
- Will the code samples have syntax highlighting?
- Is the search site wide or only in-page content?
- How will access be handled?
- How do I manage the IA (information architecture)? Can it be easily updated?
- What is the learning curve for new admins?
Out of the box, Slate has only a single page. The index page is typically used by other Slate forks as a landing page (for multiple endpoints) or as a feet-first introduction to the API with a header acting as the introduction. Given the nature of API and front-end documentation, I needed to use this as a landing page.
Since Slate is based on middleman, the directory structure felt pretty straight forward. I could create subdirectories such as
/api, create a new
index.html within that, and boom: localhost:4567/api/. The main issues I ran into when working with this were three-fold:
- The information architecture could easily become convoluted from a user or developer side. With two major API versions, I needed
/api/v3/. On top of that, there are 25 resources or more (not including subresources) to cover in the documentation. I had to decide which was the lesser of two evils: a very long page (but one with search and side-nav) or many subdirectories and landing pages.
- [Lesson learned way later] Pages with a lot of content can have some interesting issues in Slate. Specifically, using the navigation, some content wouldn't show up until you refreshed but the page had fully loaded. The way I had Slate deployed was via github pages, so the site was pre-built with static html. There was no JS or back-end nonsense that should have prevented rendering. I never figured this one out.
- If I wanted multiple pages within the same subdirectory, it was relatively easy to name the file something like
index.html. The issue I had with this was relatively minor, but the final html rendering between various gems didn't like this in a few places (tables). It also hampered the search effectiveness without a federated search like Algolia.
In my attempt to have every endpoint on the same page by version (
/api/v2/), the js generating the side-nav was taking ages. It totaled about 1s+ on desktop. I presented a bit on using Nokogiri for pre-rendering the table of contents as I had worked on it asynchronous from Lord (Slate's creator). After implementing the Nokogiri pre-rendering, load times were 👌. By changing the ToC (table of contents) build function from client-side to sorta-server-side, the greatest damage was mitigated.
As a static site, there was no full-site search but Slate did have in-page search with lunr.js. My only change was to the highlighting feature. I noticed with large pages, there was a significant feeling of lag after a single character had been typed. Increasing this to three characters was more likely to be relevant to the user without impacting their experience.
Since leaving the company where I implemented this, they will also be incorporating Algolia as a federated search across multiple sites. It is a great solution and would've worked well with Slate using DocSearch.
During the development process, the company I was working for was in the midst of building a new major API version. This API version featured Swagger specs for each endpoint (and I was overjoyed for that). This presented an interesting project.
In the past, every API update was documented by hand. I had done this by reading PHP and others had done this by talking to the engineers or digging through Jira tickets and pull requests. Swagger offered a consistent format, an existing editor that provided documentation and examples, and had an ecosystem to support it. With primary contributions from a product manager that loves code, we ended up using Widdershins to consume the swagger file and output Slate-compatible markdown. Widdershins also helped create code samples using doT.js for templating.
If you're working with Slate or evaluating it and have questions, feel free to ping me regarding them. 🕺