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
- Install
react-refractor
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