Sanity Minimum Viable Schema
10 Jun 2020
Table of Contents
- Get a Sanity.io account
- Install Postman on your computer
- Install Node.js on your computer
- Install the Sanity CLI from npm
- Log your command line into your Sanity account
- Find your temporary Sanity account API key
- Create and edit a new Sanity project in Postman
- Create a dataset for your Sanity project in the web management console or Postman
- Initalize your project structure into a folder on your computer in the Sanity CLI
- Edit the project schema on your computer
- Deploy the project from your computer to Sanity’s cloud
- Do some data entry in Sanity Studio in the cloud
- Double-check your data exists with Postman
- Delete the project folder off your computer if you’d like
- Log your command line out of your Sanity account
- Uninstall the Sanity CLI from your computer if you’d like
- Thoughts
What did I have to do to make Sanity Studio work in the cloud?
Playing with CMSes after being inspired by Jamstack Conf, I tried Sanity.io as leveraged by Stackbit with its pre-built Azimuth template and demo data.
Stackbit’s UI has a few weak points that I didn’t think a content author would enjoy, but I noticed that Sanity Studio kind of made up for that as an “alternative UI” to editing the same web site content.
So I thought, “Okay, how do I set up a data model from scratch in Sanity and get it working with a Sanity Studio instance in the cloud?”
Get a Sanity.io account
Install Postman on your computer
Install Node.js on your computer
Install the Sanity CLI from npm
Log your command line into your Sanity account
Find your temporary Sanity account API key
Create and edit a new Sanity project in Postman
Create a dataset for your Sanity project in the web management console or Postman
Initalize your project structure into a folder on your computer in the Sanity CLI
Edit the project schema on your computer
I had 4 files in the /schema/
folder: schema.js
, address.js
, venue.js
, and event.js
schema.js
// 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'
// We import object and document schemas
import address from './address'
import gig from './event'
import venue from './venue'
// 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([
// The following are document types which will appear
// in the studio.
gig,
venue,
// When added to this list, object types can be used as
// { type: 'typename' } in other document schemas
address
])
})
address.js
export default {
name: 'address',
title: 'Address',
type: 'object',
fields: [
{name: 'street', type: 'string', title: 'Street number and name'},
{name: 'cityStateZipCountry', type: 'string', title: 'City, State, Zip, Country (as applicable)'},
]
}
venue.js
import icon from 'react-icons/lib/md/location-city'
export default {
name: 'venue',
title: 'Venue',
type: 'document',
icon,
fields: [
{
name: 'venueName',
title: 'Venue Name',
type: 'string'
},
{
name: 'venueAddress',
title: 'Venue Address',
type: 'address'
},
{
name: 'venueShorthand',
title: 'Venue Shorthand',
type: 'slug',
description: 'If not happy with what the system generated, you can hand-edit it here',
options: {
source: 'venueName',
maxLength: 50
}
}
],
preview: {
select: {
name: 'venueName',
cityState: 'venueAddress.cityStateZipCountry'
},
prepare(selection) {
const {name, cityState} = selection
return {
title: `${name} [${cityState}]`,
subtitle: cityState
}
}
}
}
event.js
import icon from 'react-icons/lib/md/event'
export default {
name: 'event',
title: 'Event',
type: 'document',
fields: [
{
name: 'eventTitle',
title: 'Event Title',
type: 'string',
},
{
name: 'eventShorthand',
title: 'Event Shorthand for its URL',
type: 'slug',
description: 'If not happy with what the system generated, you can hand-edit it here',
options: {
source: 'eventTitle',
maxLength: 50
}
},
{
name: 'image',
title: 'Image',
type: 'image',
options: {
hotspot: true
}
},
{
name: 'venue',
title: 'Venue',
type: 'reference',
to: [{type: 'venue'}]
},
{
name: 'startDateTime',
title: 'Start Date & Time',
type: 'datetime'
}
],
preview: {
select: {
title: 'eventTitle',
venue: 'venue.venueName',
startDate: 'startDateTime',
media: 'image'
},
prepare(selection) {
const {title, venue, startDate, media} = selection
return {
title: title,
subtitle: `${startDate} [${venue}]`,
media
}
}
}
}
Deploy the project from your computer to Sanity’s cloud
Do some data entry in Sanity Studio in the cloud
Double-check your data exists with Postman
Delete the project folder off your computer if you’d like
It’s pretty big.
Log your command line out of your Sanity account
Your API key will stop working in Postman
Uninstall the Sanity CLI from your computer if you’d like
Thoughts
This is a lot of work that Stackbit did on my behalf. Particularly parsing the data stored in the cloud, since a full Postman dump seems to include old draft junk and such.
I never bothered to figure out if there’s a way to get Sanity Studio to make fields required, or to generate slugs without someone having to click the button.
I’m not convinced 10,000 objects is enough for a 20-year event history.
- I suppose I could go back to basics and use Netlify CMS or something and use some sort of Git Hooks or whatever to combine into JSON. That was a beastly project I never finished, though.
Overall, even though the CMS UI is kind of decent, having a bunch of data that could be represented as files in a filesystem not be downloadable as such (as with Git-backed CMSes) makes me a little antsy.
- What it is about me liking to see the data and feel that it’s at my fingertips to have as “mine” with a Git “download ZIP” rather than a Postman call that returns JSON?
- I mean, I know perfectly well that build times for a static site’s events widgets should be better as a mega-JSON than as a million files.
The idea of proceeding next to Stackbit is kind of overwhelming me.
I wonder if I should look into whether TinaCMS blocks could offer what I want (like Stackbit & Sanity, it needs to support draggable blocks inside of draggable blocks if it’s really going to be Squarespace-like).
Interesting – I wonder if I’ve been under-configuring “datetime” in other CMSes. Looks like I can turn a datetime into a time-picker by setting a value to “false.” Anyway, TinaCMS definitely seems to support doing that.