Static website generators (SSG) are top-rated technologies to build websites. And the reasons are obvious: they offer flexible content edition, and the deployed sites have the best performance.
Now I'm using Gatsby, and things are different from other SSG. Beyond the buzzwords that are React and GraphQL, Gatsby switches the way I think about the website I build: from a content-oriented one to a programmatic one.
At its core, an SSG is a tool that transforms simplified markup into HTML: for each of the original files, you get a new HTML file. However, the simplified markup is only here to help you edit the content, and you write the shell hosting the content with a complete template language.
With Jekyll, you cannot configure the type of markup or the templating engine. With others, you can pick plugins depending on your preferences. With both approaches, you get the same kind of tool: a pipeline in which each step pushes transformed content to the next.
So traditionally, SSGs use a push model. This model limits the possibilities of sources to the one foreseen by the SSG creators. And in practice, those sources are the markup files or, in the best case, any file.
When I was in charge of some JS open-source projects at Algolia, proper documentation was vital. When you make documentation for such projects, you realize it's hard to be exhaustive without JSDoc (or documentation.js), and it's hard to make a beautiful website without the tooling offered by SSGs. So the obvious is to try mixing both.
Because of the push model, you have to work around the way the SSG work:
- in the case of Jekyll, you can generate markup files and then integrate them
- in the case of an SSG built around plugins, like Metalsmith, you can write a plugin with the limitation of only working with virtual files (which is the fundamental brick for content in Metalsmith)
Both methods feel very hacky, and because of that, they are tough to maintain.
You have guessed it already: Gatsby uses a pull model for the content. It is not the content that creates the pages; it's the code that pulls the content and creates the pages.
The content is available through GraphQL. Each content plugin provides an API that allows the code to query the content. The content can be plain files or markdown files. The more specific is the plugin, the more specialized is the API: when using the markdown plugin, the GraphQL API provides the content in rendered HTML and can generate the excerpts.
There is no limitation on the source either, so working with comments in the source file is not an issue. So much so, that there is a plugin for documentation.js(a JSDoc alternative).
The documentation example is unusual; other use cases leverage this API, and the headless CMSs are the perfect candidate. The GraphQL API is just a layer on top of the HTTP API those service offer. The use of such services decouples the architecture. It reduces the need for servers even more while providing superior user experience.
Last but not least, media assets benefit from the pull approach too. With the GraphQL API, you can query the images you need and retrieve a structure that contains all the URLs of the optimized alternatives of the source file.
With SSGs before Gatsby, you would not write the HTML with the same templating engine when you move to the front-end. Juggling with templating systems is particularly tricky when writing a single page app (SPA) because writing two implementations lead to discrepancies. To the point that you would not traditionally use an SSG when writing an SPA.
React is the templating engine, and Gatsby acts as a server-side rendering framework: only one template per piece of HTML. It's the same code that runs at runtime and during the static generation. The reuse of templates eliminates the possibilities of bugs due to discrepancies completely.
Because of the component approach and the fixed data structures of GraphQL fragments, the plugins can provide a unified and user-friendly API to the developers.
The combination of the two technologies hides the complexity, and it provides a seamless developer experience.
The Gatsby team could have continued the work laid out by previous tools. At some point, they flipped the content access model. They might not have done that intentionally, but what stays is a different approach.
As a library writer and DX practitioner, the lesson to me is clear: sometimes, you need to change what is familiar to something else. If you change this at a fundamental level, like querying the content instead of pushing the content down the pipeline, you get ripples everywhere.
Changing the content paradigm from push to pull is a trade-off towards more flexibility, more power, and also more work for the developer. How much more work is hard to evaluate, here are some pointers:
- The Gatsby architecture is intricate; this can be daunting even if you don't have to master it entirely.
- With Gatsby, you use React and GraphQL, which you need to learn the fundamentals to get started.
- If you need to make a single page app or a PWA, Gatsby is helpful. If you know Vue, you should consider the Vue flavor.
After considering the previous points, here are for me the selling points of Gatsby:
- Best performance built-in (gatsby-image is just amazing)
- Unified DX for the static generation and the live website
- Super active community
- Great documentation
Thanks for reading this post, it means a lot if you could share it. I'm wondering, have you tried Gatsby yet? Do you want to try? Why not?
This post was first published on Noima.xyz blog.