As developers, we often search for the cleanest architectural solution. This empowers us to write code that allows for future flexibility, and can withstand changes in the direction of a project.
When using a content management system to build out content infrastructure, your chosen architectural solution also affects how you model your content. We would like to outline an advisory tale—that weighs up flexible content model abstraction—with tight client budgets. We will also be touching on the difficulties associated with trying to model products in a CMS and how we dealt with them.
First, some background: The client was working with an outdated, non-scalable method of managing content and wanted to scrap that for a proper, modern solution that would enhance their workflow. In particular, they wanted to facilitate the ability to create reusable content with a long shelf life, saving time and allowing non-technical users to move components and reorder content layout.
This revamped marketing site would include:
A product hire section
A slick store locator
A decoupled full site search
A super fast experience
In the past, we’ve used classic CMS solutions, with many features ready from the get-go. However, often we found that the features were never been quite what we wanted. So, we would then build on top of the CMS — locking ourselves into a big, unwieldy system.
Our solution here was to build a static website with content powered by Contentful. This fit the bill as we tried our hand with the decoupled approach and content infrastructure on this project. This type of solution also improves system user productivity by modernizing the way users work with content.We knew from our testing that static sites certainly ticked the box from a performance perspective, so we just needed to crack the content modeling side of things.
Our team consisted of developers that had heavy React experience, so we chose GatsbyJS to generate our static sites. The timeline for this project was tight — four two-week sprints from zero to launch. In addition, the client’s general budget was lean, so we had to carefully choose expensive SasS products and tailor plans to keep costs down.
Below are some wireframes for the landing pages — they are reasonably conventional, to be honest. The key thing here was that the client needed full flexibility to spin landing pages up and insert or edit content as they wished, in any order. They did not want to be locked down to a fixed template that allowed for little customisation.
After joining the Contentful team in Berlin for an awesome training session on content modeling, we felt fully prepared to give it a shot. This was our first iteration of our content model for non-product data:
The first thing to note is the "blocks" reference field in the custom template type. The custom template type is effectively the model for a page. Having a "blocks" area allowed for content editors to drop any other component they wanted and re-order this list to completely change the layout of their page — ace.
Secondly, you might notice that all our components also have a "container" content type. Hopefully the developer side of your brain will be ticking over right now and you can see that this extra level of abstraction allowed us to do some quite powerful things within Gatsby. We could effectively loop through the "blocks" field of a page and identify the components needed throughout, mapping Contentful components dynamically to React components.
It also allowed us to keep our content types very pure. In the past we’ve run into situations where we have had to use flags such as "switch sides" or “columns” to define the layout of the content. With a container content type, you can add website-specific layout flags to your components, without littering the raw content component, which could just as easily be consumed by other media, such as Amazon Alexa or Google Home.
We began to develop the site using this as a basis for our content modeling and components. It worked very nicely within Gatsby and our codebase was feeling clean. However — we hit a few dealbreaking caveats:
Editing content was sometimes confusing for editors due to the extra abstraction
We were using a lot of content models
In terms of the editor experience, this problem can be fixed with enough education and training. A conversation that outlines the benefits of this approach would have most editors sold on the extra hoops they might have to jump through. Plus, Contentful’s admin interface is really nice and clean anyway, so it’s pretty hard to get lost.
However, the escalating amount of content models was an issue. The client couldn’t afford the upgrade to next tier Contentful plan, which meant we were stuck. The only thing we could reasonably do was undo the extra level of abstraction and take away our "container" content models. So we did. Effectively, the content entry job became slightly easier, but the code was more messy.
So,what’s our main takeaway here? Should you abstract content models for better architecture? Yes and no.
Obviously, every project is different, but we’ve found that often, hard-coding a "landing page" content type is just too restrictive for the long term. We’re always keen to break things down into small components and encourage re-usability — hence our appetite for abstraction.
Our product pages are fairly typical of e-commerce product pages. It’s worth noting that the site was not transactional, so the site did not need to be able to take payments. However, we still had the challenge of modeling the products in a way that allowed for product "variants" and fairly specific product data. This is the content model we came up with:
The most important thing to note here is the fact a "product" could link to a “page” which could link to a “product”. And so, we ended up with a clever way to create product variants, any level deep — much like a parent/child relationship in UI navigation.
However, when it came time to map these relationships within our GraphQL layer within Gatsby, it turned out to be quite difficult! Gatsby relies on a unique slug for each page it creates. For us, each product variant needed a unique page, nested under a parent product slug. So, tracing this hierarchy back from a flat data tree which Contentful provides was a challenge. However, we eventually got there and ended up with a fairly robust setup.
You (quite rightly) might be asking: "Why would you model products in a CMS?"
For us it came down to:
A lack of existing infrastructure / tooling
No desire to add more SaaS products
Small amount of products
In our case, using the CMS as a product information management system made sense. In fact, it was really the only choice we had. And it can be done. However, in hindsight, our recommendation would be to try to use a PIM if at all possible. A PIM is specifically designed to model thousands or tens of thousands of products, while a CMS is more adept at serving general content.
From there, you could use Contentful to pull in your product data as read-only fields, allowing you to decorate your products with additional content. We have yet to try this approach, but are looking forward to giving it a go! A PIM and CMS working hand-in-hand, each with their own specialty has the potential to save time for developers and editors alike, but also requires more architectural consideration up front.
Finally, I wanted to touch on some of the areas where Contentful seriously impressed us.
The interface is beautiful. It’s fast, lightweight and friendly, and superior to the traditional CMSes we’re used to. Developers were genuinely very productive in less than a day. Editors also picked things up quickly, as we were able to limit what they could see and create views to allow them to focus on the job to be done.
To lock down certain areas of the admin section, we used the built-in user roles. Again, these were so easy to use. Often, big traditional CMS systems allow for very granular roles and permissions, which on the surface sounds great. However, as these systems grow in complexity, managing roles becomes increasingly difficult. Contentful have got this spot on.
Contentful’s APIs, documentation and support are also top notch. It’s always a good sign when developers start posting documentation links around the internal Slack channels as they like what they are seeing. Our interactions with Contentful’s support also gave us a great impression, especially the direct contact with experts at Contentful.
Both the fact that this was a static site — and that it was powered by Contentful — was a first for us. Our advice from this experience would be to consider the following when dealing with modeling a web project geared towards products:
Think about the content that you’re modeling. Is it general or specialized? Specialized content tends to have multiple categories, data subsets and types (such as a product).
Be aware of your budgets, especially when deciding how much to abstract your content models. Often you will have to weigh a more scalable solution against budget.
Extra features such as ecommerce prices and taxes would be included with a PIM, but you could also make this work within Contentful by building extensions, or by using front-end magic.