Salesforce, Python, SQL, & other ways to put your data where you need it

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

Sanity Minimum Viable Schema

10 Jun 2020 🔖 architecture tips web hosting
💬 EN

Table of Contents

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.

--- ---