Discussion on using code input for <BlockContent> frontend and transitioning to Next.js with Sanity

16 replies
Last updated: Aug 24, 2022
How do you add the code input for the <BlockContent> frontend?
AI Update

To add code input support to your Sanity project and render it on the frontend, you'll need to set up both the Studio configuration and the frontend rendering. Here's how:

Studio Setup

First, install the @sanity/code-input plugin:

npm i @sanity/code-input

Then add it to your sanity.config.ts:

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

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

Schema Configuration

Add the code type to your schema, typically within a Portable Text array:

{
  name: 'content',
  title: 'Content',
  type: 'array',
  of: [
    {type: 'block'},
    {
      type: 'code',
      options: {
        withFilename: true,           // Allow adding filenames
        highlightedLines: true,        // Enable line highlighting
        languageAlternatives: [        // Optional: restrict languages
          {title: 'JavaScript', value: 'javascript'},
          {title: 'TypeScript', value: 'typescript'},
          {title: 'Python', value: 'python'}
        ]
      }
    }
  ]
}

Frontend Rendering with @portabletext/react

For rendering on the frontend with @portabletext/react, you need to create a custom serializer for the code type:

import {PortableText} from '@portabletext/react'

const components = {
  types: {
    code: ({value}) => (
      <pre data-language={value.language}>
        <code>{value.code}</code>
      </pre>
    )
  }
}

// In your component
<PortableText value={content} components={components} />

For a more feature-rich implementation with syntax highlighting, you can use libraries like Prism or Highlight.js:

import Refractor from 'react-refractor'
import javascript from 'refractor/lang/javascript'

Refractor.registerLanguage(javascript)

const components = {
  types: {
    code: ({value}) => (
      <div>
        {value.filename && <div className="filename">{value.filename}</div>}
        <Refractor
          language={value.language || 'text'}
          value={value.code}
        />
      </div>
    )
  }
}

Code Block Data Structure

The code input data structure includes:

  • code: The actual code string
  • language: The programming language identifier
  • filename: Optional filename (if enabled with withFilename)
  • highlightedLines: Optional array of line numbers to highlight (if enabled)

This gives you a fully functional code input experience in Sanity Studio with proper rendering on your frontend! The Code Input plugin documentation has additional details if you need more advanced configurations.

There's an example in the docs that should be helpful if you haven't finished setting up the back end https://www.sanity.io/docs/configuration#8d1dbe8a8b56
But since you said the front end, the official page for the plugin has an example:

https://www.sanity.io/plugins/code-input (see the heading Example usage in frontend (React) ) where they're using this package to consume it.
I think I'm using v2 because I don't see how this would work for BlockContent
&lt;BlockContent blocks={singlePost.body}
/&gt;
I was going to ask you where that component came from because I didn't recognize it but I think this is the repo? https://github.com/sanity-io/block-content-to-react#block-content-to-react
If that's the case, under the heading there's a recommendation to use
https://github.com/portabletext/react-portabletext moving forward, if that's an option for you.
v2 is a default bit it also shouldn't be relevant to the front end (there's a strong separation of concerns with the Studio environment and your actual pages, intentionally)
I got it from Kapehe
I see. At the time it was valid; it happens to be an uncommon change in the year and a half since that video was posted.
Sounds like I'm going have to redo the entire site 😞
Not really; they work very similarly. If you uninstall the old package and install the newer one, they simply take option props in a different format but were designed to process portable text in just the same way. Their pages on GitHub can walk you through the differences, and you have the community hear to lean on if you have specific questions.
I'm considering redoing it from ReactJS to Nextjs
Next.js is really popular here and a great fit with Sanity.
There are specific aids:
https://www.sanity.io/exchange/framework=nextjs include auth helpers and am image tool: https://www.sanity.io/plugins/next-sanity-image
And an entire toolkit
https://github.com/sanity-io/next-sanity including convenience methods.
Also, because Next.js has API routes and Sanity (the service) has a webhook implementation when you make major document changes in the Studio software, you can easily take advantage of on-demand revalidation for incremental static regeneration which is now a stable feature.

There's also a
nextjs channel here for relevant topics.
Thank you
with blog comments
I'm going to do the create template nextjs
Awesome. Let me know if you run into bumps. That template was one of the first things that that piqued my interest. I couldn't believe how fast pages were loading. I used to do WordPress sites all the time and by comparison everything is a bogged down wait (and weight!)
Awesome. Let me know if you run into bumps. That template was one of the first things that that piqued my interest. I couldn't believe how fast pages were loading. I used to do WordPress sites all the time and by comparison everything is a bogged down wait (and weight!)

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?