Here at Novvum, we are a software development firm that specializes in React, GraphQL, TypeScript, Node and so much more. Therefore, we enjoy building with modern technologies like Gatsby. Sadly, up until now, our website did not follow this trend.
A few months ago we decided it was time to give our site a much-needed upgrade. We always take great pride in designing and architecting cutting-edge web applications for our clients, but we hadn’t given much thought to our site and were still using a drag and drop editor for simplicity. Why? We would love to say that we were just too busy building awesome software for our clients, which is partially true, but we were also reluctant to upgrade because we needed a site that could be edited and designed by non-technical members of our team while still providing great performance and features.
Our requirements and motivations
Finally, after hearing enough about how our site was not reflective of our work from our partners and friends, we decided it was time to take the plunge and upgrade all of our sites. As we set out on this multi-website rebuild, we had a few key requirements for the codebase and maintenance workflows for the project.
The components, configurations, and functionalities needed to be reusable across all our company’s sites and easily accessible for future sites.
Landing pages
Blog
Internal documentation
Client Portal / Auditing Platform
Each site needed to be deployable, editable and extendable on its own without affecting the other clients
Content like blogs, audits and case studies needed to be easily edited by non-technical team members without diving into the codebase
All site's code/logic should be available in a single monorepo, while content (markdown/MDX) files should be available on their own and abstracted from the core logic.
As you can tell, most of the requirements set out to simplify the experience of composing functionality across different sites while still maintaining a separation of concerns between each domain and its deployment. We also wanted to keep non-technical content editing separate from feature development. To handle this, we used a combination of the following tools and techniques. I won't dive into them all but it gives you a decent idea of our configurations.
- Gatsby Themes
- Yarn Workspaces
- Git Submodules
- CI/CD with Gitlab
In this article, I will dive into the composition of our Gatsby themes and how we were able to tackle these requirements while simplifying the development workflow for all our websites.
Gatsby Themes as building blocks
If you haven’t heard of Gatsby it is a super-fast static site generator that allows you to use GraphQL to query your site’s configuration, assets and markdown files. It is extremely performant and customizable. Gatsby is the perfect fit for websites, blogs, eCommerce and other content focused sites because the markdown files containing content can easily be edited by technical and non-technical team members. Besides, Gatsby offers Gatsby themes that allow site functionality to be packaged as a standalone module so functionality can easily be reused. Rather than using starters or templates for every website you build, all the default configuration lives in an NPM package, that can be updated and shared across independent projects. This helped us provide a consistent yet adaptable experience across our main website/blog, client portal, and documentation website. Any changes to the underlying theme(s) will update on all current and future sites. Providing a seamless development workflow.
Here is how the architecture maps out:
The diagram outlines how we are using Gatsby Themes to share components and functionality across our suite of websites.
base-theme
: Holds many of the core pieces of functionality across all Novvum sites. This includes theming, presentational components, utilities and more. Think of this as the more fundamental building block.
blog-theme
: The blog theme is what it sounds like, the theme for all blog-specific functionality. This includes the blog specific components and routing information.
wiki-theme
: This theme is specific to our internal documentation site and handles the routing and components needed to display out internal documentation. There is more on this theme and the motivation for its abstraction below.
auth-theme
: One of the more interesting themes, this theme includes all the necessary modules for authentication. Plug it in and your deployed website has auth.
Composing themes
Initially, it is easy to assume Gatsby Themes are best used for styling and components. However, with some creativity, Gatsby Themes can provide a great way to share configuration, functionality, and logic for almost anything. It is not to much different from just deploying individual NPM modules.
So, Rather than dive into the more fundamental use cases for themes like using them to share UI and components, I want to quickly review how our auth-theme
(green block) is currently being used to extend our client portal and internal documentation sites. Also, dive into how themes can provide a great abstraction for content files written in markdown
and mdx
. These are two ways we tackled our requirements in a creative way and may provide you with some inspiration.
Sharing logic + ui
Sometimes sharing a site logic can be a pain and may even require redundant code across websites. However, by using the basic Gatsby Theme concepts, we can share our authentication module across all of our sites.
By simply adding the auth-theme
to the Client Portal
and Internal Documentation
gatsby-configs
, we can extend both sites to with our prepackaged, consistent authentication module. In this case, we are using Netlify Identity for simplicity but this idea would not change for other more custom implementations. In our case, the auth theme` includes helper functions for user management, sign in modals, private routes and other key authentication functionalities. Now, if we ever want to include auth on any other sites, we just add that theme to the config and we are off and running. This is the same with the styling theme and component found in the base Gatsby Theme.
Abstracting away content from code
Another powerful feature of Gatsby Themes is the ability to extend themes with themes. Above you may have noticed the blue block inside the blog-theme
and wiki-theme
modules. That blue block is our base-theme
which provides fundamental theming and components to all of our websites including the internal documentation and blog. This may seem a bit like themeception, but let me explain our thought process:
If you remember from above, one of our requirements was the ability of non-technical team members to edit and add content like blog articles and documentation without needing access to the entire codebase.
Well, by creating a blog-theme
or wiki-theme
, we can abstract all of the blog and documentation logic away from the final deployed site. Here is a look at the final internal documentation site's file structure and gatsby-config
file:
├── public
├── content (all .md & .mdx files)
| ├── assets
| ├── guides
| ├── index.mdx
| └── projects
├── gatsby-config.js
├── netlify.toml
├── package.json
├── README.md
Woah! There is no src
directory, meaning there are no React components! This is made possible because all of that code lives in the separate wiki-theme
. This leaves the repo simple while only exposing the markdown files found in the content
folder. Now content creators and non-technical team members can quickly add and edit content without knowing much about how the site works. The themes even handle routing, so new markdown
(mdx
in our case) files and folders automatically create new routes that will display information properly. The only reference to the theme can be found in the gatsby-config
file.
module.exports = {
__experimentalThemes: [
{
resolve: "@novvum/gatsby-theme-wiki"
}
],
Of course, another option for reaching this level of abstraction may be to use a CMS like Contentful. However, for small and midsized teams, this works great.
Okay, how do you work on all these abstractions together?
Well, that's where the monorepo, submodules, and Gitlab CI/CD comes together. With the current setup, you can interact with the codebases in a few ways.
- You can directly edit content in the individual repos
blog
,internal documentation
- You can directly edit site functionality in the individual repos.
- You can edit all codebases in unison through our master monorepo. This monorepo includes submodules for each of the deployed
sites
as well as all thethemes
. Here is the folder structure:
├── clients
| ├── audit (submodule)
| ├── blog (submodule)
| ├── web (submodule)
| └── documentation (submodule)
├── themes
| ├── base
| ├── blog
| ├── gatsby-theme-auth
| └── gatsby-theme-wiki
├── lerna.json
├── package.json
├── README.md
This monorepo provides a superuser workflow to add, edit and change each of the separate themes and sites while still maintaining a separation of concerns. If only editing one of the clients is preferred, one can just clone and work in the specific site's repository without access to the underlying themes. This offers a bunch of flexibility!
Great, so now what?
Now that we have a flexible, scalable and robust underlying architecture for the Novvum suite of sites our team is confident we will be able to easily iterate, collaborate and extend our online presence without losing consistency. Need a new website? Add it to the monorepo, extend a theme and you are off an running!
If you are interested in learning more about any of the underlying concepts in this article, I would love to dive into the details on my next blog. Or if you have thoughts on how to improve this, we would love to hear from you.
To check out our new home go to novvum.io
Top comments (0)