Rendering Code Blocks in Sanity and Next.js

Cover Image for Rendering Code Blocks in Sanity and Next.js

How to render block code in sanity and Nextjs by using react @portabletext/react


1. Install @sanity/code-input

npm install @sanity/code-input

2. Add it as a plugin in sanity.config.ts (or .js):

import {codeInput} from '@sanity/code-input'

export default defineConfig({
  // ...
  plugins: [codeInput()],
})

3. Now you can use the code type in your schema types:

//...fields,
defineField({
  type: 'code',
  name: 'myCodeField',
  title: 'Code with all options',
  options: {
    language: 'javascript',
    languageAlternatives: [
     { title: "Javascript", value: "javascript" },
     { title: "TypeScript", value: "typescript" },
     { title: "tsx", value: "tsx" },
    ],
    withFilename: true,
  },
})
Example usage in frontend (React)

1. Install @portabletext/react

npm install @portabletext/react
// page.tsx
import { client } from "../../lib/sanity.client"
import { postQuery } from "../../lib/sanity.queries"
import { PortableText } from "@portabletext/react";

type Props = {
  params: {
    slug: string;
  };
};

export default async function Post({ params: { slug } }: Props) {
  const post: Post = await client.fetch(postQuery, { slug });

  return (
  <div>
    <PortableText value={post.body} components={RichTextComponents} />
  </div>
  )
}

2. Customising components

npm install react-refractor
  • Usage
// RichTextComponents.tsx
import Refractor from "react-refractor";
// Load any languages you want to use from `refractor`
import js from "refractor/lang/javascript";
import typescript from "refractor/lang/typescript";
import tsx from "refractor/lang/tsx";

//You'll need to register the languages you want to use 
Refractor.registerLanguage(js);
Refractor.registerLanguage(typescript);
Refractor.registerLanguage(tsx);

export const RichTextComponents = {
  types: {
    myCodeField: ({ value }: any) => {
        return (
          <Refractor language={value.language} value={value.code} />
        );
    },
  },
}
  • Stylesheets are not automatically handled for you - but there is a bunch of premade themes which you can simply drop in and they'll "just work".

And that's it! There are many more interesting use cases, some of which I hope to cover in the future.

Reference:

https://www.sanity.io/plugins/code-input

https://github.com/portabletext/react-portabletext

https://github.com/rexxars/react-refractor

https://github.com/PrismJS/prism-themes


More Stories