Some pages of your website on production return error 500. You don’t know why. There have been no recent code changes, so it must be connected with a content update.
Ondrej PolesnyPublished on Dec 20, 2021
Restricting the implementation
We, developers, like to be restricted. When we implement a web application, we prefer type-safe languages so that we discover potential issues as soon as possible—either while coding or at build time. We add unit and integration tests to make sure our changes don’t have side effects and that everything stays working.
But every website has two components: the code and the content. The measures I mentioned above give us confidence in the code part, but what about content?
Sure, we have a granularly defined content model, we’ve carefully prepared every content type, limited the usage of content items in Linked items and Rich text elements, defined roles in a way that disables unauthorized people to change content types, but still—is that enough? Does it also protect us from ourselves?
This is a screenshot of the Audit log showing the latest changes to the Kontent.ai website content model. As you can see, model changes are not that uncommon, especially on large websites. In our case, they were all performed by a single person—the lead developer on the project—and in a separate environment. It does, however, demonstrate that there exists a risk in relying on a single person, or worse, multiple developers, to keep the implementation up to date with all these changes.
Adding strongly-typed content and structure
What is the worst that can happen? If you’re thinking about a broken build, that’s the least of a problem. If the build fails, you know something is wrong. It’s much worse if some pages start returning error 500, show other errors, or even behave normally with missing content. The runtime problems are the worst since they’re hard to find.
So how do we solve the situation?
Using generated codenames
In the new version 11, when using the generated project structure, it looks like this:
This solves both the typos and the codename changes.
Keeping generated types up to date
Moving forward on the content gathering query, the returned items are mapped to the
BlogPost type. All pages and components that use it can benefit from type safety as long as the generated type is up to date with its corresponding content type BlogPost in the headless CMS.
We achieve that by regenerating the types before every production build.
The headless CMS is the source of truth for the content model and the generated types. Not the site implementation. However, we, developers, like to keep track of all the changes, and we want to have the generated types committed in source control.
Therefore, to discover type mismatches, we’ll incorporate a check into the production build pipeline. We’ll generate a fresh set of types into a temp folder and perform a simple directory diff against the types we have in our implementation.
First, we install the
dir-compare module that will take care of the comparison:
Then, we’ll add a Node script
verify-types.js that will:
- Generate the types from the current content model in Kontent
- Compare them with our tracked types
- Stop the build in case there are any differences
Note: If you adjusted the configuration of the model generator in your project, make sure to configure it the same way in the script too.
The script expects a single parameter—the path to the directory of your generated types:
Make sure the script is at the root level of your project and adjust the production build script in
Note: My project is based on Next.js, your build script may be different.
Remember, you only want to verify models on a production build. On local, it’s fine to do it manually, as the content model changes are typically less frequent than you running
npm run dev.
Failing build = issue avoided
Now, when there’s a content change and you need to do a full or a partial rebuild of production, the build server will first generate the types and compare them to those that you track in your implementation. If there’s a difference, the build will fail with an error showing you exactly what’s different:
Note: In this case, the content type
Block with image was changed.
Your production site remains untouched until you resolve the issue.
Note: If you use the project structure constants in your code, also codename changes will stop the build even though they are harmless. I personally like to know about these changes too, but feel free to update the verify-models.js script to ignore them.
In this article, I showed you how a content model change can be dangerous to your production website and suggested checking the generated models and project structure of your content with the headless CMS during every production build. This step adds safety and helps you avoid unexpected issues where it could hurt you the most.
Find the links to the mentioned resources below and make sure to join our community on Discord if you need help or want to discuss your project specifics.