A couple weeks ago, I had to figure how to serve dynamic content for my personal website. While researching, I was led to the concept of a CMS (Content Management System). Most CMSs have the concept of the frontend and backend both being included, but that wouldn't work for my use case, since I already had a frontend up and running.
Headless CMS
This is where I learned about the concept of a Headless CMS. The concept of a Headless CMS is that you only get the backend, and instead you ping an API for your data.
I started searching for a good list of Headless CMSs, but none of them were quite as quick to setup as I expected. Most of them required you to host them somewhere, and I definitely did not want to spend money in order to host my stuff on a server.
Introduction to Sanity
While I was searching for a good CMS for my website, a certain Benjamin Ashbaugh (yes, I can confirm he is a cow) in Hack Club's Slack workspace told me about a certain CMS called Sanity. It didn't require me to host my own instance anywhere and was really easy to edit through a tool called Sanity Studio.
So I decided to give it a try, since the worse that could happen is that I don't have a good experience and lose hours of my life ¯_(ツ)_/¯
Let's-a-go!
Sanity has a really good starter guide to introduce you to the technology, so I would recommend following that to get the basic repository set up
Difference between Sanity Studio and Content Lake
Sanity Studio is a really intuitive tool used to manipulate data from Sanity itself (sort of like how Prisma Studio). Content Lake is the data itself that comes from handling data in Sanity Studio. Clients can access the Content Lake from the API that Sanity provides.
Schema
After you get Sanity Studio working, you're probably going to have to generate a schema.
One file will be labeled schema.js
, which will be the gateway to our schema. Here is an example of it:
// First, we must import the schema creator
import createSchema from "part:@sanity/base/schema-creator";
// Then import schema types from any plugins that might expose them
import schemaTypes from "all:part:@sanity/base/schema-type";
import project from "./project";
// Then we give our schema to the builder and provide the result to Sanity
export default createSchema({
// We name our schema
name: "default",
// Then proceed to concatenate our document type
// to the ones provided by any plugins that are installed
types: schemaTypes.concat([
/* Your types here! */
project,
]),
});
You might be wondering what exactly is the project
import doing there. Well, that's our second file, the actual schema of the entity in question, project.js
. Here is an example of that file:
export default {
name: "project",
type: "document",
title: "Project",
fields: [
{
name: "name",
type: "string",
title: "Name",
},
{
name: "description",
type: "string",
title: "Description",
},
{
name: "demo",
type: "string",
title: "Demo",
},
{
name: "github",
type: "string",
title: "Github",
},
{
title: "Technologies",
name: "technologies",
type: "array",
of: [{ type: "string" }],
},
{
title: "Image",
name: "image",
type: "image",
}
],
};
Here, first of all, we import an object as the default export. Then, we define the name
, type
, and title
. In our project.js
file, we specify that it is a "document"
. Now, you might be wondering the difference between the name
and the title
. The name is most likely how Sanity refers to the data internally, while title
is just how it's presented to the user.
The fields
array contains a bunch of objects specifying the different fields in the schema. You can find more about schema types here
Sanity Client
To access data from the Content Lake, I'm going to use a client for Sanity. Alternatively, you can use the HTTP API.
I'm going to use the Node.js API, so I can simply install it with
npm install @sanity/client
or
yarn install @sanity/client
Then, we are going to create a new file (anywhere you want) with any name you want (I'm going to use client.js
)
Then, use the code
import sanityClient from "@sanity/client";
export const client = sanityClient({
projectId: "PROJECT_ID_PROVIDED_IN_SANITY.JSON",
dataset: "DATASET_PROVIDED_IN_SANITY.JSON"
useCdn: true,
});
Here, we're using the useCdn:true
, because the CDN is much faster to respond and gives us more API calls in our free tier. Although, it doesn't update the content as quickly as without the CDN, so do keep that in mind.
Then, to get the content, we can use
const projects = await client.fetch(
`
*[_type == "project"]
`
);
This basically selects everything document that has the type of "project" (e.g. every piece of content that follows the schema in project.js
from the earlier example. Remember to run this in an async
function by the way.
If you're curious about the query language that is used by Sanity, check out the guide here and the cheatsheet
End
So that's pretty much. Leave a reaction on the beautiful panel to your left (or a comment below)!
Follow me on Twitter: https://twitter.com/ShubhamPatilsd
Follow me on GitHub: https://github.com/ShubhamPatilsd
Top comments (3)
Can I use Sanity io interface for users of a site to edit their information? e.g. If I create a blogging site could users use a sanity io interface to add their articles following a schema I set and permissions I set?
I've looked into appwrite and sanity and not sure if these would be the best use case.
Yes. You absolutely can. When you take advantage of the relations between schemas, you should be able to achieve that.
That's one of the reasons I like Sanity - you have control over how your content works
Quick guide on the Javascript client on how to create documents :)
sanity.io/docs/js-client#creating-...