Upgrading the stack
I have not been too active on this site, but when I am, there are aspects of the publishing process and performance of the site that are bothering me. For example, working with content on Contentful (note: free edition) has been a little bit bothersome on mobile since the interface is very much catered towards desktop usage. I have found my self very often having to write some thoughts down into what can be a future post and this experience has been less then delightful with Contentful.
Furhtermore, I have been troubled by very long page-loads on my site. Hosting my site on Vercel, I have been monitoring the performance of my site using their Speed Insights SDK for some time now, and I have seen the time to first contentful paint been up to 6 seconds, and while I could improve this on my end with streaming updates and moving more of my site to render as you fetch, the Contentful CMS API seems to be a major bottleneck with response times of around 4 seconds on what I suspect are cold-starts.
Moving to Sanity
I have been tipped about Sanity from multiple friends and after checking it out, it seems their platform aligns better with my needs. I created an accound and copied over some of my Contentful content to test it out a little bit before deciding to perform the actual migration.
Migrating to a monorepo
Sanity comes with a Santy Studio feature that allows users to locally
- Create and publish new content using a visual editor
- Test queries towards their content lake
The content schema is also defined locally in code, which means that there are options to export the schema so that types for queries and schemas can automatically be generated with the sanity typegen generate command from their cli package. Since I don't want to switch between two different repositories at all times, and also not pollute my site-code with Sanity specific infrastructure, I decided to migrate my single-package repository to a monorepo consisting of two packages:
@haakonsvane/site-frontend@haakonsvane/site-studio
I then switched from using npm to pnpm as my package manager as it performs much better in monorepos and installed turbo as my build tool to speed up the build process.
With this workflow, I can edit the schema of my content and generate typescript types for queries into it locally and all in the same place. When I was using Contentful and their GraphQL API earlier, this required me to change the schema visually, manually export the graphql schema from their platform and import it into my local repo before generating.
No more GraphQL,
Though I am quite the fan of GraphQL, I decided to instead rely on Sanity's GROC language. It works rather similarly as GQL, but I suspect there might be performance benefits to using it over any of the other query options. This migration meant I had to rewrite how I fetch data from my site and learn a thing or two about GROC. For example, a GraphQL query that requests the title and synopsis of all my blog posts might have looked like this:
query BlogPostQuery {
blogPostCollection(order:sys_publishedAt_DESC) {
items {
title,
synopsis
}
}
}
With its GROQ query counterpart looking like this
*[_type == 'blogPost'] | order(_createdAt desc) {title, synopsis}
I don't care for the fact that the GROQ query is smaller, but learning it has at least been interesting, and it seems to be performing rather fast
Migrating content
The content migration itself was a little bit of a pain in the ass. There is no way to manually set system fields created by sanity like _createdAt, and since I didn't spend too much time looking into tools that can migrate for me, I ended up manually copying data over from Contentful to Sanity in the same order as I originally posted them to preserve this. Looking back at things now, I wish I did spend some time researching migration tools however.
Upsides and downsides
Though switching to using Sanity has come with a great deal of upsides such as
- Closer control over my schema and content
- Better experience creating, editing and publishing content
- Increased query performance
I personally don't align very well with Sanity's phisosophy too much. For example, the fact that they have created their own query language is a little bit of a worrying to me. There might be some technical aspects of the decision to create this query language that I am just not seeing yet, but the consequences of creating it is that they now have to take ownership over lots of repercussional artifacts such as their own typegen engine. Using Sanity, you therefore rely on lots of libraries created and maintained by them such as their block to text library, image url library and so on. Because of this I am little bit afraid being too tied in with them due to vendor lock in. Maybe it is in their financial interest to have it designed like this? In that case, I suggest they instead start focusing on making a great product.