Published on 27 February 2025 by Andrew Owen (5 minutes)
In January last year, I was up for a documentation manager role and I needed to come up with a solution that would serve the needs of writers and developer-contributors. My solution looked something like this:
I was the second choice, so fortunately for me I didn’t have to deliver it. Instead, I ended up getting a gig where I had to build a documentation portal solution that presented REST and GraphQL APIs in a somewhat consistent manner. That was based on Magidoc, the free Redocly CLI tool, and a lot of scripting. Since then, I’ve discovered Archbee. It’s a Markdown-based system with proprietary extensions for presenting REST and GraphQL APIs. Even if I’d known about it at the time, I don’t think I would have chosen it based on documented reliability issues. However, having used it recently for another client, I think it might just be production ready for user docs. It offers a nice web interface, but you can use your own GitHub repository as the source of truth. Changes made in the web editor create pull requests in the repo. It has search and sites can be password protected. It has built-in support for Mermaid diagrams and dark mode. It’s quite reasonably priced and because it’s Markdown you’re not locked in.
But I’m still a fan of DocBook. Was there an off-the-shelf solution that looked more like my hybrid document management system (DMS) proposal? One possible solution would be Magnolia CMS, the Antora static site generator (SSG) and AsciiDoc. However, Magnolia doesn’t disclose its pricing. And if you ever wanted to migrate to another system, you’d have to build it yourself because other headless CMS solutions don’t support AsciiDoc.
Which lead me back to Markdown. Was there an SSG primarily aimed at producing doc sites that would work with my favorite headless CMS (TinaCMS)? That led me to Docusaurus. It’s what Meta (Facebook) built to replace Jekyll as its in-house SSG and it uses React. Its build times can feel like an age compared to Hugo. But the sites it builds are so much faster. But was there a better free REST API docs integration than hacking the output of Redocly CLI? The answer was yes, with a great Docusaurus plugin from Palo Alto Networks. All I should have had to do to set it up was to create a new site using the Tina Docusarus starter and then add the plugin. It wasn’t that straightforward. Palo Alto Networks has drunk the TypeScript KoolAid. Because Docusaurus is React, the starter site created by Tina uses JSX. They did not want to play nicely. I ended up creating a site from the Palo Alto Networks template and then grafting Tina support onto it.
I couldn’t figure out a way to enable the versioning and localization widgets in the nav bar with the Tina solution, so I reverted to using a fixed definition for those. For most other settings, Tina uses JSON files that are referenced by the config. Adding Mermaid and Lunr search support was trivial, although search only works in production. Rather than try to talk you through everything I had to do to get it working, this time I thought I’d simply share the repo. The Palo Alto Networks component is made available under the MIT license, so I’ve used the same license. The only config you’ll need to do is to add your Tina credentials to enable online web editing.
Going back to the requirements, we’ve got a GitHub repo with Actions. Docusaurus replaces Hugo as the SSG. We’re using Markdown Extended (MDX) in place of AsciiDoc. We can still use LanguageTool with TinaCMS and VScode. We’re using Tina in place of the XML Mind editor. We’ve got Mermaid diagrams, with preview in Tina. We’re using Lunr for search, but if that’s insufficient, there’s built-in Algolia support. There’s a plug-in for Matomo analytics. There’s a plug-in for GraphQL docs. Docusaurus includes versioning and localization support. We can still use DeepL for machine translation. We can still use Pandoc for print output to PDF or Word for export to Affinity Publisher.
What’s missing is variables and conditional text. I’ve heard of LaunchDarkly being used to for the latter. For variables, Syed Muhammad Ali Raza provides a solution on Stack Overflow:
variables.mdx
, with variable components defined using React props.variables.mdx
file and placing it in your page.When I’ve got variables working, I’ll update the repo. I’ve done a bit of React coding before for an e-commerce solution, but that was a long time ago, so you may need to figure this out yourself.