Structured Content from Sanity

  • Marie Curie
Sanity logo Sanity logo

In the first post of the Ruhrpot project, we discussed how to use structured content to build a simple media page section. The content was defined in the Frontmatter YAML Object of the source page. In this post, we will source all content from the Sanity CMS. There will be no source file; structured content will be fetched from the Sanity API and directly injected into the Metalsmith metadata layer.

About Sanity.io

Sanity.io is a content platform that allows you to create, edit, and manage structured content such as text, images, and other media. It provides a real-time data store for storing and managing this content and APIs for interacting with it. Sanity.io also offers a content editing environment called Sanity Studio, a single-page application that allows us to quickly set up and customize an editing environment for our content. In addition to the data store and Studio, Sanity.io also provides a range of SDKs, libraries, and tools that enable us to query content and integrate it with other websites, services, and applications.

Learn how to get started with Sanity here: https://www.sanity.io/docs/getting-started-with-sanity

To use the Sanity Studio, we first define the structure of our content using schemas. A schema is a JSON object that represents the types of content that can be created, the fields that can be used to store data, and the relationships between different types of content.

A practical example the Sanity way

In this example, we will model the media section from our previous blogpost. While our last implementation was done with a YAML object in the file frontmatter, this time, we will create the media section content with Sanity Studio, which our Metalsmith SSG can then fetch during build time. We will discuss how that works in the next blogpost.

The media section schema

import {defineType} from 'sanity'

export default defineType({
  name: 'mediaBlock',
  title: 'Media Block',
  type: 'object',
  fields: [
    {
      name: 'blockOrder',
      title: 'Block Order',
      type: 'string',
      options: {
        list: [
          { title: "Image Right", value: "imageRight" },
          { title: "Image Left", value: "imageLeft" },
        ]
      },
      initialValue: "imageRight",
    },
    { name: 'titlePrefix', 
      type: 'string', 
      title: 'Title Prefix' 
    },
    {
      title: 'Title',
      name: 'title',
      type: 'string'
    },
    {
      name: "headerType",
      title: "Header Type",
      type: "string",
      description: 'Choose from h1 through h6',
      options: {
        list: [
          { title: "h1", value: "h1" },
          { title: "h2", value: "h2" },
          { title: "h3", value: "h3" },
          { title: "h4", value: "h4" },
          { title: "h5", value: "h5" },
          { title: "h6", value: "h6" },
        ]
      },
      initialValue: "h2",
    },
    {
      name: 'subTitle',
      type: 'string',
      title: 'Subtitle',
    },
    {
      name: 'mediaImage',
      title: 'Media Image',
      type: 'imageBlock',
    },
    {
      name: 'portableTextBody',
      type: 'simpleBlockContent',
      title: 'Portable Text Body',
    },
    {
      name: 'cta',
      type: 'cta',
      title: 'CTA',
    },
  ],
})

Here is the JSON Object schema that defines an object called mediaBlock with several fields, including headerType and portableTextBody. The headerType field is a list that allows us to select from a list of options. portableTextBody is a rich text field using a format called Portable Text, which is different from the markdown format used in the previous example. Once the values for the mediaBlock object have been entered into Sanity Studio, they can be published and made available through the Sanity API.