Recently, I came across this tweet (or is it “xeet”?), which initially piqued my interest because it reminded me that so much content work still happens in spreadsheets. That train of thought led me down a path where I started thinking about the true value of composability.
In the tweet, Akuya explained that he was trying to bring content from Google Sheets to the Sanity Content Lake. He found a way to do it with a bit of coding. Having the privilege of being more familiar with the platform, I also found a way to do it without having to write custom code—but by leveraging some shell scripting:
$ curl https://docs.google.com/spreadsheets/d/SHEET_ID/gviz/tq\?tqx\=out:csv\&sheet\=SHEET_NAME \
| npx csvtojson \
| npx groq "*" -i json -o ndjson \
> data.ndjson \
&& npx sanity dataset import data.ndjson production
If you aren’t familiar with shell scripting, don't worry, what you see above is a way to connect and run small programs that can take in some information and output it. In the example, we’re seeing:
- the spreadsheet data as comma-separated-values (CSV), passing that data on to
- a small program that translates CSV into a JSON format, then on to
- another program that translates the array of JSON objects into newline delineated objects (NDJSON), and then passes that data on to
- the Sanity command line interface that imports the data into individual documents in the Content Lake
You might be thinking, “Wouldn’t it be easier if Sanity had a CSV importer?” —and I don’t disagree, it would be practical. But this example clearly shows that you aren’t dependent on whether or not Sanity has a particular feature in order to get your work done. Because we have the foundational APIs and abstractions, you can do stuff like this with little effort.
The shell environment (what you can access in Terminal.app if you are on a Mac or Command/Power Shell on a Windows) was designed as a composable platform. You can “pipe” information in and out between programs. The shell was a godsend for engineers and computer users, and decades after its conception, it’s still widely used. (For the curious, this episode of Command Line Heroes does a good job of telling the history of “the shell.”)
You might have noticed that Sanity started calling ourselves the “Composable Content Cloud” last year. We’ve never been comfortable with the term “headless CMS,” because we feel we offer something a bit different (and better). Maybe you see this as a marketing ploy, but trust me: the terminology is meaningful and precise. I’ll explain a bit more, and hopefully, you might feel inspired to try new things with our platform.
On the surface, Sanity might look like a CMS. Still, if you look closer, it’s actually a collection of standalone technologies that work well together: Sanity Studio, Content Lake, a range of useful APIs, and supporting libraries and tooling for working with structured content.
This setup is based on the same idea from my original example of the shell environment: with a composable platform, you can quickly and efficiently pass information anywhere you need to. While most headless CMSes (or DXPs) have focused on omnichannel content delivery, we put just as much (if not more!) focus on how you aggregate, store, and manage the content (and data) that gets distributed to any channel.
What does it take to make a content solution truly composable? If you’re used to thinking about traditional CMSes, these factors might not be obvious:
- Content Lake, the document store, is schema-less, meaning you can put any piece of structured content in and query it freely with GROQ. That makes it easy to get content the way you want it, where you need it. And it puts less pressure on nailing your content model at the get-go. Migrations are mainly about transforming the shape of documents, not database models.
- You can freely get content out of Content Lake with GROQ (or GraphQL), but it also has a powerful API for programmatically updating content. We have yet to see a CMS-like system that lets you point to specific content within a nested structure and only change that piece (rather than overwriting the whole document and unintentionally losing someone else's work).
- Sanity Studio is made to be customized from the ground up, and we designed Studio v3 so that you can compose its built-in functionality with your own components. This means you can give your team the gift of efficiency by creating a workspace that supports their unique content types and workflows.
- Sanity Studio is also fully decoupled from Content Lake and built on the same APIs you can access. Not only can you change and customize your studio, but you are also free to have multiple studios (or none) that interact with the same collection of content.
- From its conception, we built the platform for real-time collaboration; you can have humans and programmatic services interact with and update the content without dealing with document locking. This foundational feature is extremely hard to add to a platform later in a meaningful way. For example, our new feature Sanity AI Assist, lets you work in the document alongside it and even navigate away without disrupting its work.
- Most rich text editors store content as HTML or as a JSON structure with many “HTMLisms.” This confines a huge chunk of your content to web surfaces—not reusable or composable. We made specifications like Portable Text to be presentation agnostic so you can take all of your content with you across the web and its different frameworks as well as into native apps, publishing tools, etc. It also makes it possible to query rich text and block content, create references, and update it programmatically.
So, that’s what composability means to us. But what does it mean to our customers?
We recently talked to a famous design house and fashion brand in the Nordics, and they had an interesting perspective. They were looking to composable technologies because they occupied a sweet spot between an inflexible monolith that was overly opinionated and an unwieldy range of micro-services that bring high maintenance and development costs.
When we’re talking about “composable” in the context of content management, I think it’s important to consider whether it’s possible to get the content out of the system and to what degree you are enabled and empowered to integrate and interact with the content inside it. It’s all about how the technology sits between and plays with other technologies.
It’s not enough to simply add “APIs” like many CMSes have done; there must also be enough flexibility in the system itself to accommodate your needs. For example, flexibility to model content in a way that’s more true to how your organization works and more resilient to different needs, channels, and website (re)designs.
Composable technologies like Sanity offered the company mentioned above flexibility and convenience. Thus, they could focus their resources on core business needs. In other words, they (mostly) let us worry about scaling the APIs to be performant during high-traffic times while not blocking them from doing things the way they wanted to.
Remember the shell scripting example from earlier? This mix of flexibility and convenience is similar. I could have written the code by hand, but it would have taken more time. Or I could’ve looked for a CMS that had a direct Google Sheets integration, but chances are it would do other things in a way I didn’t like.
Instead, I could quickly assemble some tools and get the desired result. That’s the magic of composability.