TypeScript Gatsby Boilerplate


How to Set Up Sanity.io as a Headless CMS for Your Personal Blog

20 March 2023

I will walk you through the steps of setting up Sanity.io as a backend panel for your personal blog. I'll cover installing Sanity and necessary plugins. I'll set up basic schemas and deploy the site to Netlify. You'll have a functioning headless CMS for your blog.

Initialise project

Create project with Sanity docs - https://www.sanity.io/docs/create-a-sanity-project.

npm create sanity@latest

Plugins

Add icons for custom Portable Text editor.

npm install react-icons --save


Add Code Input for pasting multiple lines of samples.

npm install @sanity/code-input

import {codeInput} from '@sanity/code-input'
// ...
export default {
  // ...
  plugins: [deskTool(), codeInput()],
  // ...
}

Schemas

Remove all schemas and take follow:

import {RiArticleLine} from 'react-icons/ri'

export default {
  name: 'post',
  title: 'Articles',
  type: 'document',
  icon: RiArticleLine,
  fields: [
    {
      name: 'title',
      title: 'Title',
      type: 'string',
    },
    {
      name: 'slug',
      title: 'URL path',
      type: 'slug',
      options: {
        source: 'title',
        maxLength: 96,
      },
    },
    {
      name: 'publishedAt',
      title: 'Published at',
      type: 'datetime',
      validation: (Rule: any) => Rule.required().error('A published date is required'),
      options: {
        dateFormat: 'DD.MM.YYYY',
        timeFormat: 'HH:mm',
        timeStep: 15,
        calendarTodayLabel: 'Today',
      },
    },
    {
      name: 'description',
      type: 'text',
      title: 'Description',
    },
    {
      name: 'readMore',
      title: 'Read more text',
      type: 'string',
    },
    {
      name: 'content',
      type: 'blockContent',
      title: 'Content',
    },
  ],
}
import {FaSuperscript, FaSubscript} from 'react-icons/fa'
import {TbLetterCaseLower} from 'react-icons/tb'
import {BsCodeSlash} from 'react-icons/bs'

export default {
  title: 'Block Content',
  name: 'blockContent',
  type: 'array',
  of: [
    {
      type: 'block',
      title: 'Block',
      styles: [
        {title: 'Normal', value: 'normal'},
        {title: 'H1', value: 'h1'},
        {title: 'H2', value: 'h2'},
        {title: 'H3', value: 'h3'},
        {title: 'H4', value: 'h4'},
        {title: 'Quote', value: 'blockquote'},
      ],
      lists: [
        {title: 'Bullet', value: 'bullet'},
        {title: 'Number', value: 'number'},
      ],
      // Marks let you mark up inline text in the block editor.
      marks: {
        // Decorators usually describe a single property – e.g. a typographic
        // preference or highlighting by editors.
        decorators: [
          {title: 'Strong', value: 'strong'},
          {title: 'Emphasis', value: 'em'},
          {title: 'Underline', value: 'underline'},
          {title: 'Strike', value: 'strike-through'},
          {title: 'Code', value: 'code', icon: BsCodeSlash},
          {title: 'Superscript', value: 'sup', icon: FaSuperscript},
          {title: 'Subscript', value: 'sub', icon: FaSubscript},
          {title: 'Small', value: 'small', icon: TbLetterCaseLower},
        ],
      },
    },
    {
      type: 'image',
    },
    {
      type: 'code',
      name: 'code',
      title: 'Code Highlighting',
      options: {
        language: 'javascript',
        languageAlternatives: [
          {title: 'TypeScript', value: 'typescript'},
          {title: 'Javascript', value: 'javascript'},
          {title: 'HTML', value: 'html'},
          {title: 'CSS', value: 'css'},
          {title: 'JSON', value: 'json'},
          {title: 'YAML', value: 'yaml'},
        ],
        withFilename: true,
        theme: 'monokai',
      },
    },
  ],
}

GitHub

  1. Create a repository - https://github.com/new.
  2. Connect repo and local folder: git remote add origin path-to-repo.git.
  3. Start new branch: git checkout -b feature/sanity.
  4. Commit Initial commit.

Linting

  1. Lint files with ESLint: npm init @eslint/config.
  2. Format with Prettier: npm install --save-dev --save-exact prettier.
  3. Create config file: echo {}> .prettierrc.json.
  4. Bind prettier with eslint: npm install --save-dev eslint-config-prettier.
{
  "printWidth": 80,
  "tabWidth": 2,
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none",
  "bracketSpacing": true,
  "arrowParens": "avoid",
  "proseWrap": "always"
}
{
  "extends": [
    "some-other-config-you-use",
    "@sanity/eslint-config-studio",
    "prettier"
  ]
}
  1. Point TypeScript config file in parserOptions.project.
{
   "format": "prettier --write schemas/**/*.ts",
    "lint": "eslint --fix schemas/**/*.ts",
    "test": "npm run format && npm run lint"
}
  1. Commit Add linting.

Pre-commit hook

Lint files before commiting them with husky: npx husky-init && npm install.

Commit Add pre-commit hook.

Deploy

Just use Netlify.

Git issue

If the problem is "main and master are entirely different commit histories.", the following will work.

git checkout feature/sanity

git branch main feature/sanity -f

git checkout main

git push origin main -f