Leon

How to add code block into Sanity Studio’s Block Content editor

Topics
Sanity
Published on 
5 Jan 2025

To add code blocks into Sanity Studio's Block Content editor and display them with syntax highlighting in a Next.js project using TypeScript, follow these steps:

Step 1: Install Required Packages

First, navigate to your Sanity project directory and install the necessary packages:

1npm i @sanity/code-input
2npm i react-syntax-highlighter
3npm i --save-dev @types/react-syntax-highlighter

then add it as a plugin in sanity.config.ts (or .js):

1import {codeInput} from '@sanity/code-input'
2
3export default defineConfig({
4  // ...
5  plugins: [codeInput()],
6})

Step 2: Define Your Custom Schema Types

n your Sanity schema (e.g., schemas/blockContent.ts), define the custom block types you want to use. Here’s an example that includes a code block and an image block:

1import { defineType, defineArrayMember } from 'sanity';
2
3export default defineType({
4  title: 'Block Content',
5  name: 'blockContent',
6  type: 'array',
7  of: [
8    defineArrayMember({
9      type: 'block',
10      styles: [{ title: 'Normal', value: 'normal' }],
11      marks: {
12        decorators: [{ title: 'Strong', value: 'strong' }],
13      },
14    }),
15    defineArrayMember({
16      type: 'code',
17      title: 'Code Block',
18      options: {
19		    language: 'javascript', //Default language for this code field.
20		    languageAlternatives: [
21		      {title: 'Javascript', value: 'javascript'},
22		      {title: 'HTML', value: 'html'},
23		      {title: 'CSS', value: 'css'},
24		    ], //Array of languages that should be available
25		    withFilename: true, //Boolean option to display input field for filename
26		  },
27    }),
28    defineArrayMember({
29      type: 'image',
30      title: 'Image Block',
31    }),
32    // Add more custom types as needed
33  ],
34});

Step 3: Create Custom Components

Create React components for each of your custom block types.

1// libraries for image component
2import Image from "next/image";
3import { PortableTextComponents } from "next-sanity";
4import { urlFor } from "@/sanity/lib/image";
5// libraries for code block component
6import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
7import { materialDark } from "react-syntax-highlighter/dist/esm/styles/prism";
8
9export const components: PortableTextComponents = {
10  types: {
11    image: (props) =>
12      props.value ? (
13        <Image
14          className="rounded-lg not-prose w-full h-auto"
15          src={urlFor(props.value)
16            .width(600)
17            .height(400)
18            .quality(80)
19            .auto("format")
20            .url()}
21          alt={props?.value?.alt || ""}
22          width="600"
23          height="400"
24        />
25      ) : null,
26    //Here is the custom component for showing code block in block content
27    code: (props) => {
28      if (!props.value) return null;
29      const {code, filename, language} = props.value;
30      return (
31        <>
32        <SyntaxHighlighter language={language} style={materialDark}>
33          {code}
34        </SyntaxHighlighter>
35        <span>{filename}</span>
36        </>
37      );
38    },
39  },
40};