An Intro to Dynamic Docs
When people get to writing docs, they usually have a few different thoughts about how they are going to actually deploy and publish the docs. Some online searches will give you some good starting points:
- A static site generator like Hugo, Jekyll, Docusaurus and some others
- Confluence.
- Some Software as a Service (SaaS) offering
- Something else
Generally, any of these are better than none, and some of them are better than others. The point of this post isn't necessarily to rank any of the above but to propose a different angle to consider when thinking about your docs. That is, rather than thinking about what tool should build your docs, consider where you store and retrieve them.
Having a look at static site generators
I've had a number of jobs over the years. Ranging from CCTV, to enterprise software support, to writing content, UX and technical documentation. Something that surprised me when moving to writing was how many options exist to put your content on, and how all of them always end up feeling a bit... clunky.
As a technical writer coming from a computer science background, I naturally fell into the group of people that follow the 'docs-as-code' approach. In a sense that I write docs and posts using the same tools as developers: Git, VSCode, maybe AWS depending on how far we're going. This brings me nicely to my next point.
Keep content and frontend separate
I'm a big fan of clean markdown, with absolutely nothing else in it. I'm also a big fan of sites that do things automatically and dynamically. With this mindset it means static sites like Hugo fail my test because:
- It requires a full build to publish new docs
- It uses partials to embed a code-like syntax into markdown files
What does a clean, automated and dynamic site look like?
A solution that ticks all the boxes for me ends up being a multi-tiered architecture:
- Docs stored in a repo
- A build script lists all the docs and their filepaths into a manifest.json, and builds a search index in the same pass
- Push the docs and manifest to a location, such as an S3 bucket, writing a small pointer file last so a half-finished upload is never visible
- Your docs site reads the manifest server-side
- Your site then builds the navigation from the manifest
- Each page is fetched and rendered on the server, so readers and crawlers get real HTML instead of a blank shell that fills in after a chain of browser requests
Docs live completely separate from frontend source code
The docs are completely separate, if you have less technically minded writers working in your docs you don't need to worry that they might accidentally make a mistake in the codebase. On top of this, your docs now have an extra fallback should a system go down. If you lose access to your frontend, the docs are clean and ready to stand up somewhere else in an emergency. The trade-off is that the site now leans on that remote location at read time, but a cache sitting in front of it means a brief origin blip doesn't take the docs down with it. This obviously means you have the inherent benefit of version control, but that's a standard docs-as-code approach too.
Docs can be published (nearly) instantly
Because the frontend doesn't bundle the docs at build time, publishing is just pushing the new files and flipping the pointer - no site rebuild, no redeploy.
The one catch is caching: if you've put a CDN in front of the remote location for speed, the idea of being instant only holds if publishing (pushing) your new docs also removes the cached pointer. Wire that idea into the publish step and you get both - fast, cached reads almost all of the time, and fresh docs the moment you ship them.
Search comes from the same build
Splitting content out from the frontend raises a fair question: how does anyone actually find a doc? The trick is to build the search index in the same pass that builds the manifest. It ships as just another file alongside the docs, the site pulls it in once, and search stays quick without ever being dragged back into a frontend build.
SEO can still exist with this approach
One question that some might have with this approach is about SEO. You could argue that SEO for a docs site isn't important but that depends on the situation. Regardless, let's suppose you want to use this approach for a blog or news site. You will want to have decent SEO.
With dynamic docs, you want to emulate the idea of the static version. If we consider the likes of Hugo, it renders your markdown into HTML ahead of time and serves those finished pages, so it has an easy job of handing Google something to index. With dynamic docs, our server doesn't even necessarily know where the docs are coming from.
You can work with this though. The key is where the rendering happens. Even though the docs are fetched from some remote location, you do that fetch on the server rather than in the reader's browser. The server grabs the manifest, pulls the doc it needs, renders the whole page to HTML, and sends that finished HTML back in the response. As far as Google is concerned, there's no difference to a static site: a complete page turns up. The only thing that changed is that the page was put together on demand instead of baked ahead of time.
That's the whole trick really - a dynamic source with static-looking output. You keep the freedom to fetch docs from wherever you like, and crawlers still get real HTML to eat.
Serve multiple frontends the same docs
One unspoken benefit so far is that by separating the content into its own location, you make it available to any other app that might want to use it, whilst maintaining one golden source. Consider an application that needs to present guidance in the UI. Instead of retyping the same content again (and potentially again), just make a call to the S3 and retrieve the doc you need.
I'll go into a bit more detail on the specifics of this setup in later posts. I just think it's neat!